moderndash 2.3.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -55,7 +55,7 @@ npm install moderndash
55
55
  ```
56
56
  ## 📋 Requirements
57
57
 
58
- **NodeJS**: >16.14 | **Typescript**: >4.7
58
+ **NodeJS**: >=16.15 | **Typescript**: >=4.8
59
59
 
60
60
  > `NodeJS 16-18`: Enable the [experimental-global-webcrypto](https://nodejs.dev/en/api/v16/cli#--experimental-global-webcrypto) flag to use crypto functions.
61
61
  > `TypeScript 4.8-4.9`: Enable the [experimentalDecorators](https://www.typescriptlang.org/tsconfig#experimentalDecorators) flag to use decorator functions.
package/dist/index.cjs CHANGED
@@ -118,18 +118,19 @@ function fastArrayFlat(arrays) {
118
118
  }
119
119
 
120
120
  // src/array/difference.ts
121
- function difference(arrayOrCompFn, ...arrays) {
122
- const withCompareFn = typeof arrayOrCompFn === "function";
123
- const firstArray = withCompareFn ? arrays.shift() : arrayOrCompFn;
121
+ function difference(...arraysOrCompareFn) {
122
+ const compareFnProvided = typeof arraysOrCompareFn.at(-1) === "function";
123
+ const compareFunction = compareFnProvided && arraysOrCompareFn.pop();
124
+ const arrays = arraysOrCompareFn;
125
+ const firstArray = arrays.shift();
124
126
  const combinedRestArray = fastArrayFlat(arrays);
125
- if (!withCompareFn) {
127
+ if (!compareFunction) {
126
128
  const restSet = new Set(combinedRestArray);
127
129
  return firstArray.filter((element) => !restSet.has(element));
128
130
  }
129
- const compareFN = arrayOrCompFn;
130
131
  const difference2 = [];
131
132
  for (const element of firstArray) {
132
- if (combinedRestArray.every((item) => !compareFN(item, element))) {
133
+ if (combinedRestArray.every((item) => !compareFunction(element, item))) {
133
134
  difference2.push(element);
134
135
  }
135
136
  }
@@ -181,18 +182,19 @@ function unique(array, compareFn) {
181
182
  }
182
183
 
183
184
  // src/array/intersection.ts
184
- function intersection(arrayOrCompFn, ...arrays) {
185
- const withCompareFn = typeof arrayOrCompFn === "function";
186
- const firstArray = unique(withCompareFn ? arrays.shift() : arrayOrCompFn);
185
+ function intersection(...arraysOrCompareFn) {
186
+ const compareFnProvided = typeof arraysOrCompareFn.at(-1) === "function";
187
+ const compareFunction = compareFnProvided && arraysOrCompareFn.pop();
188
+ const arrays = arraysOrCompareFn;
189
+ const firstArray = unique(arrays.shift());
187
190
  const combinedRestArray = fastArrayFlat(arrays);
188
- if (!withCompareFn) {
191
+ if (!compareFunction) {
189
192
  const restSet = new Set(combinedRestArray);
190
193
  return firstArray.filter((element) => restSet.has(element));
191
194
  }
192
- const compareFN = arrayOrCompFn;
193
195
  const intersection2 = [];
194
196
  for (const element of firstArray) {
195
- if (combinedRestArray.some((item) => compareFN(item, element))) {
197
+ if (combinedRestArray.some((item) => compareFunction(element, item))) {
196
198
  intersection2.push(element);
197
199
  }
198
200
  }
@@ -747,13 +749,11 @@ function deburr(str) {
747
749
  function camelCase(str) {
748
750
  str = deburr(str);
749
751
  const words = splitWords(str);
750
- const camelCase2 = words.map((word, index) => {
751
- if (index === 0) {
752
- return word.toLowerCase();
753
- }
754
- return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
755
- });
756
- return camelCase2.join("");
752
+ let camelCase2 = "";
753
+ for (const [index, word] of words.entries()) {
754
+ camelCase2 += index === 0 ? word.toLowerCase() : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
755
+ }
756
+ return camelCase2;
757
757
  }
758
758
 
759
759
  // src/string/capitalize.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/array/chunk.ts","../src/array/count.ts","../src/helpers/fastArrayFlat.ts","../src/array/difference.ts","../src/array/dropRightWhile.ts","../src/array/dropWhile.ts","../src/array/group.ts","../src/array/unique.ts","../src/array/intersection.ts","../src/array/range.ts","../src/array/shuffle.ts","../src/array/sort.ts","../src/array/takeRightWhile.ts","../src/array/takeWhile.ts","../src/crypto/hash.ts","../src/crypto/randomInt.ts","../src/crypto/randomElem.ts","../src/crypto/randomFloat.ts","../src/crypto/randomString.ts","../src/decorator/toDecorator.ts","../src/function/debounce.ts","../src/decorator/decDebounce.ts","../src/function/maxCalls.ts","../src/decorator/decMaxCalls.ts","../src/function/memoize.ts","../src/decorator/decMemoize.ts","../src/function/minCalls.ts","../src/decorator/decMinCalls.ts","../src/function/throttle.ts","../src/decorator/decThrottle.ts","../src/function/times.ts","../src/number/sum.ts","../src/number/average.ts","../src/number/median.ts","../src/number/round.ts","../src/validate/isPlainObject.ts","../src/object/flatKeys.ts","../src/object/merge.ts","../src/object/pick.ts","../src/object/omit.ts","../src/object/set.ts","../src/promise/queue.ts","../src/promise/races.ts","../src/promise/sleep.ts","../src/promise/retry.ts","../src/promise/timeout.ts","../src/promise/tryCatch.ts","../src/string/splitWords.ts","../src/string/deburr.ts","../src/string/camelCase.ts","../src/string/capitalize.ts","../src/string/escapeHtml.ts","../src/string/escapeRegExp.ts","../src/string/kebabCase.ts","../src/string/pascalCase.ts","../src/string/snakeCase.ts","../src/string/titleCase.ts","../src/string/unescapeHtml.ts","../src/validate/isEmpty.ts","../src/validate/isEqual.ts","../src/validate/isUrl.ts"],"sourcesContent":["export * from './array';\nexport * from './crypto';\nexport * from './decorator';\nexport * from './function';\nexport * from './number';\nexport * from './object';\nexport * from './promise';\nexport * from './string';\nexport * from './type';\nexport * from './validate';\n","/**\n * Creates an array of elements split into groups the length of size. If array can't be split evenly, the final chunk will be the remaining elements.\n *\n * @example\n * chunk(['a', 'b', 'c', 'd'], 2)\n * // => [['a', 'b'], ['c', 'd']]\n *\n * chunk(['a', 'b', 'c', 'd'], 3)\n * // => [['a', 'b', 'c'], ['d']]\n * @param chunkSize The length of each chunk\n * @param array The array to chunk.\n * @template TElem The type of the array elements.\n * @returns Returns the new array of chunks.\n */\n\nexport function chunk<TElem>(array: readonly TElem[], chunkSize: number): TElem[][] {\n const intSize = Math.trunc(chunkSize);\n if (array.length === 0 || intSize < 1) {\n return [];\n }\n \n let index = 0;\n let resultIndex = 0;\n const result = new Array(Math.ceil(array.length / intSize)) as TElem[][];\n\n while (index < array.length) {\n result[resultIndex++] = array.slice(index, (index += intSize));\n }\n\n return result;\n}\n","/**\n * Creates an object with counts of occurrences of items in the array.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true, age: 36 },\n * { 'user': 'betty', 'active': false, age: 36 },\n * { 'user': 'fred', 'active': true, age: 40 }\n * ]\n *\n * count(users, value => value.active ? 'active' : 'inactive');\n * // => { 'active': 2, 'inactive': 1 }\n *\n * count(users, value => value.age);\n * // => { 36: 2, 40: 1 }\n *\n * @param criteria The criteria to count by.\n * @param array The array or record to iterate over.\n * @template TElem The type of the array elements.\n * @returns Returns the composed aggregate object.\n */\n\nexport function count<TElem, TKey extends PropertyKey>(array: readonly TElem[], criteria: (value: TElem) => TKey): Record<TKey, number> {\n const result = {} as Record<TKey, number>;\n for (const value of array) {\n const key = criteria(value);\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n result[key] = (result[key] ?? 0) + 1;\n }\n return result;\n}","// native array.flat is much slower than this - node 19\nexport function fastArrayFlat<TElem>(arrays: (readonly TElem[])[]): readonly TElem[] {\n let result = arrays.shift() ?? [];\n\n for (const array of arrays) {\n result = [...result, ...array];\n }\n\n return result;\n}","import type { ArrayMinLength } from '@type/ArrayMinLength.js';\n\nimport { fastArrayFlat } from '@helpers/fastArrayFlat.js';\n\n/**\n * Create a new array with values from the first array that are not present in the other arrays.\n * \n * Optionally, use a compare function to determine the comparison of elements (default is `===`).\n * \n * @example\n * difference([2, 1], [2, 3], [6])\n * // => [1]\n *\n * // ---- Custom compare function ----\n * const compareByFloor = (a, b) => Math.floor(a) === Math.floor(b);\n * difference(compareByFloor, [1.2, 3.1], [1.3, 2.4])\n * // => [3.1]\n *\n * // ---- Only compare by id ----\n * const arr1 = [{ id: 1, name: 'Yeet' }, { id: 3, name: 'John' }];\n * const arr2 = [{ id: 3, name: 'Carl' }, { id: 4, name: 'Max' }];\n *\n * difference((a, b) => a.id === b.id, arr1, arr2)\n * // => [{ id: 1, name: 'Yeet' }]\n * @param arrays First array is inspected, others are excluded.\n * @template TElem The type of the array elements.\n * @returns Returns the new array of filtered values.\n */\n\nexport function difference<TElem>(...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];\nexport function difference<TElem>(arrayOrCompFn: (a: TElem, b: TElem) => boolean, ...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];\nexport function difference<TElem>(arrayOrCompFn: readonly TElem[] | ((a: TElem, b: TElem) => boolean), ...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[] {\n const withCompareFn = typeof arrayOrCompFn === 'function';\n const firstArray = withCompareFn ? arrays.shift()! : arrayOrCompFn;\n const combinedRestArray = fastArrayFlat(arrays);\n\n if (!withCompareFn) {\n const restSet = new Set(combinedRestArray);\n return firstArray.filter(element => !restSet.has(element));\n }\n\n const compareFN = arrayOrCompFn as (a: TElem, b: TElem) => boolean;\n const difference: TElem[] = [];\n for (const element of firstArray) {\n if (combinedRestArray.every(item => !compareFN(item, element))) {\n difference.push(element);\n }\n }\n\n return difference;\n}\n","/**\n * Creates a slice of `array` excluding elements dropped from the end. \n * Elements are dropped until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': true }\n * ]\n *\n * dropRightWhile(users, user => user.active)\n * // => objects for ['barney']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function dropRightWhile<TElem>(array: readonly TElem[], predicate: (value: TElem) => boolean) {\n let i = array.length;\n while (i > 0 && predicate(array[i - 1])) {\n i--;\n }\n return array.slice(0, i);\n}\n","/**\n * Creates a slice of `array` excluding elements dropped from the beginning. \n * Elements are dropped until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': false }\n * ]\n *\n * dropWhile(users, user => user.active)\n * // => objects for ['pebbles']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function dropWhile<TElem>(array: readonly TElem[], predicate: (value: TElem) => boolean): TElem[] {\n const index = array.findIndex(x => !predicate(x));\n return array.slice(index === -1 ? array.length : index);\n}\n","/**\n * Creates an object with grouped items in the array.\n *\n * @example\n * group([6.1, 4.2, 6.3], Math.floor)\n * // => { 4: [4.2], 6: [6.1, 6.3] }\n *\n * group([6.1, 4.2, 6.3], value => value > 5 ? '>5' : '<=5')\n * // => { '<=5': [4.2], '>5': [6.1, 6.3] }\n * \n * @param collection The array or object to iterate over.\n * @param getGroupKey A function that returns the group id for each item.\n * @template TElem The type of the array elements.\n * @returns An object with grouped items.\n */\n\nexport function group<TElem, TKey extends PropertyKey>(array: readonly TElem[], getGroupKey: (elem: TElem) => TKey): Record<TKey, TElem[]> {\n const result = {} as Record<TKey, TElem[]>;\n for (const elem of array) {\n const key = getGroupKey(elem);\n (result[key] ??= []).push(elem);\n }\n return result;\n}","/**\n * Creates a duplicate-free version of an array, in which only the first occurrence of each element is kept. \n * The order of result values is determined by the order they occur in the array.\n *\n * A compare function is optional to specify how the array is compared (default is `===`).\n * \n * @example\n * unique([2, 1, 2])\n * // => [2, 1]\n * \n * // compare by object values\n * const users = [\n * { id: 1, name: 'john' },\n * { id: 2, name: 'john' },\n * { id: 2, name: 'john' },\n * ]\n * \n * unique(users, isEqual)\n * // => [{ id: 1, name: 'john' }, { id: 2, name: 'john' }]\n * \n * // compare by id\n * unique(users, (a, b) => a.name === b.name)\n * // => [{ id: 1, name: 'john' }]\n *\n * @param array The array to inspect.\n * @param iteratee The iteratee invoked per element.\n * @template TElem The type of the array elements.\n * @returns Returns the new duplicate free array.\n */\n\nexport function unique<TElem>(array: readonly TElem[], compareFn?: (a: TElem, b: TElem) => boolean): TElem[] {\n // Arrays optimized with native Set\n if (!compareFn)\n return [...new Set(array)];\n\n const uniqueArray: TElem[] = [];\n for (const value of array) {\n let isUnique = true;\n \n for (const uniqueValue of uniqueArray) {\n if (compareFn(value, uniqueValue)) {\n isUnique = false;\n break;\n }\n }\n \n if (isUnique)\n uniqueArray.push(value);\n }\n \n return uniqueArray;\n}\n","import type { ArrayMinLength } from '@type/ArrayMinLength.js';\n\nimport { fastArrayFlat } from '@helpers/fastArrayFlat.js';\n\nimport { unique } from './unique.js';\n\n/**\n * Create an array with unique values from all input arrays, with order based on the first array. \n * \n * Optionally, use a compare function for element comparison (default is `===`).\n * @example\n * intersection([2, 1], [2, 3])\n * // => [2]\n *\n * // ---- Custom compare function ----\n * const compareFn = (a, b) => Math.floor(a) === Math.floor(b);\n * \n * intersection(compareFn, [1.2, 1.1], [1.3, 2.4])\n * // => [1.2]\n *\n * // ---- Only compare by id ----\n * const arr1 = [{ id: 1, name: 'Yeet' }, { id: 3, name: 'John' }];\n * const arr2 = [{ id: 3, name: 'Carl' }, { id: 4, name: 'Max' }];\n *\n * intersection((a, b) => a.id === b.id, arr1, arr2)\n * // => [{ id: 3, name: 'John' }]\n * @param arrays The arrays to inspect.\n * @template TElem The type of the array elements.\n * @returns Returns the new array of intersecting values.\n */\n\nexport function intersection<TElem>(...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];\nexport function intersection<TElem>(arrayOrCompFn: (a: TElem, b: TElem) => boolean, ...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];\nexport function intersection<TElem>(arrayOrCompFn: readonly TElem[] | ((a: TElem, b: TElem) => boolean), ...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[] {\n const withCompareFn = typeof arrayOrCompFn === 'function';\n const firstArray = unique(withCompareFn ? arrays.shift()! : arrayOrCompFn);\n const combinedRestArray = fastArrayFlat(arrays);\n\n if (!withCompareFn) {\n const restSet = new Set(combinedRestArray);\n return firstArray.filter(element => restSet.has(element));\n }\n \n const compareFN = arrayOrCompFn as (a: TElem, b: TElem) => boolean;\n const intersection: TElem[] = [];\n\n for (const element of firstArray) {\n if (combinedRestArray.some(item => compareFN(item, element))) {\n intersection.push(element);\n }\n }\n\n return intersection;\n}\n","/**\n * Generates an iterable sequence of numbers starting from `start`, up to and including `end`,\n * with a given `step` between each number.\n *\n * @example\n * for (const num of range(1, 5)) {\n * console.log(num);\n * }\n * // => 1 2 3 4 5\n * \n * // Generate an array of even numbers between 0 and 10:\n * const arr = [...range(0, 10, 2)];\n * // => [0, 2, 4, 6, 8, 10]\n * \n * @param start The starting number of the sequence.\n * @param end The end number of the sequence.\n * @param step The step between each number in the sequence. Defaults to 1.\n *\n * @returns An iterable sequence of numbers between `start` and `end`, inclusive, with increments of `step`.\n */\nexport function* range(start: number, end: number, step = 1): Generator<number> {\n if (start > end)\n throw new Error('The start of the range must be less than or equal to the end.');\n\n if (step <= 0)\n throw new Error('The step must be greater than 0.');\n \n for (let i = start; i <= end; i += step) {\n yield i;\n }\n}","/**\n * Creates a new array of shuffled values, using the Fisher-Yates-Durstenfeld Shuffle algorithm.\n *\n * @example\n * shuffle([1, 2, 3, 4])\n * // => [4, 1, 3, 2]\n * @param array The array or object to shuffle.\n * @template TElem The type of the array elements.\n * @returns Returns a new shuffled array.\n */\n\nexport function shuffle<TElem>(array: readonly TElem[]): TElem[] {\n const shuffledArray = [...array];\n \n for (let index = shuffledArray.length - 1; index > 0; index--) {\n const randomIndex = Math.floor(Math.random() * (index + 1));\n [shuffledArray[index], shuffledArray[randomIndex]] = [shuffledArray[randomIndex], shuffledArray[index]];\n }\n \n return shuffledArray;\n}","\n/**\n * Creates a new sorted array in ascending or descending order based on one or multiple sorting criteria.\n * \n * @example\n * sort([1, 2, 3, 4], { order: 'desc' })\n * // => [4, 3, 2, 1]\n * \n * // --- Sorting by multiple properties ---\n * const array = [{ a: 2, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 1 }];\n * \n * sort(array,\n * { order: 'asc', by: item => item.a },\n * { order: 'desc', by: item => item.b }\n * )\n * // => [{ a: 1, b: 2 }, { a: 1, b: 1 }, { a: 2, b: 1 }]\n * @param array The array to sort.\n * @param orders The sorting criteria, one or multiple objects with properties order (either 'asc' or 'desc') and by (iteratee function to sort based on a specific property).\n * @param orders.order - The order to sort in, either 'asc' or 'desc'.\n * @param orders.by - The iteratee function to sort based on a specific property.\n * @template TElem The type of the array elements.\n * @returns Returns a new sorted array.\n*/\nexport function sort<TElem>(array: readonly TElem[], ...orders: { order?: 'asc' | 'desc', by?: (item: TElem) => number | bigint | Date | string }[]): TElem[] {\n return [...array].sort((a, b) => {\n for (const { order, by } of orders) {\n const aValue = by ? by(a) : a;\n const bValue = by ? by(b) : b;\n if (aValue < bValue) {\n return order === 'desc' ? 1 : -1; \n }\n if (aValue > bValue) {\n return order === 'desc' ? -1 : 1;\n }\n }\n return 0;\n });\n}","/**\n * Creates a slice of `array` with elements taken from the end. \n * Elements are taken until `predicate` returns falsey.\n * \n * @example\n * const users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': true }\n * ]\n *\n * takeRightWhile(users, user => user.active)\n * // => objects for ['fred', 'pebbles']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function takeRightWhile<TElem>(array: readonly TElem[], predicate: (elem: TElem) => boolean): TElem[] {\n const result: TElem[] = [];\n\n for (let i = array.length - 1; i >= 0; i--) {\n if (predicate(array[i])) {\n result.unshift(array[i]);\n } else {\n break;\n }\n }\n\n return result;\n}\n","/**\n * Creates a slice of `array` with elements taken from the beginning. \n * Elements are taken until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': false }\n * ]\n *\n * takeWhile(users, user => user.active)\n * // => objects for ['barney', 'fred']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function takeWhile<TElem>(array: readonly TElem[], predicate: (elem: TElem) => boolean): TElem[] {\n const result: TElem[] = [];\n\n for (const element of array) {\n if (predicate(element)) {\n result.push(element);\n } else {\n break;\n }\n }\n\n return result;\n}\n","import type { Jsonifiable } from '@type/Jsonifiable.js';\n\ntype SupportedAlgorithms = 'SHA-256' | 'SHA-384' | 'SHA-512';\n\nlet textEncoder: TextEncoder | undefined;\n\n/**\n * Generates a hash from the given data using the specified algorithm.\n *\n * It uses the Web Crypto API to generate the hash.\n * \n * *Note: If you need a secure hash use a specialized library like [crypto-js](https://www.npmjs.com/package/crypto-js) instead.*\n * \n * @example\n * // Hash a string using the default algorithm (SHA-256)\n * await hash('hello world'); \n * // => \"b94d27b9934d3e08a52e52d7da7dabfac484efe37a53...\"\n *\n * // Hash an object using the SHA-512 algorithm\n * await hash({ foo: 'bar', baz: 123 }, 'SHA-512');\n * // => \"d8f3c752c6820e580977099368083f4266b569660558...\"\n * \n * @param data The data to hash, either as a string or a JSON-serializable object.\n * @param algorithm The hashing algorithm to use. Defaults to 'SHA-256'.\n * @returns A Promise that resolves to the hexadecimal representation of the hash.\n *\n * @throws {DOMException} If the specified algorithm is not supported by the Web Crypto API.\n */\n\nexport async function hash(data: Jsonifiable, algorithm: SupportedAlgorithms = 'SHA-256'): Promise<string> {\n textEncoder ??= new TextEncoder();\n\n const dataBuffer = typeof data === 'string'\n ? textEncoder.encode(data) \n : textEncoder.encode(JSON.stringify(data));\n \n const hashBuffer = await crypto.subtle.digest(algorithm, dataBuffer);\n const hashArray = [...new Uint8Array(hashBuffer)];\n const hexValues = hashArray.map(b => b.toString(16).padStart(2, '0'));\n return hexValues.join('');\n}\n","\n/**\n * Generates a random integer between two given numbers, including those numbers.\n * \n * It uses `crypto.getRandomValues` to generate the random number.\n * @example\n * randomInt(1, 10) \n * // => 5\n * \n * @param min The smallest integer that can be generated.\n * @param max The largest integer that can be generated.\n * \n * @returns A random integer between `min` and `max`, including `min` and `max`.\n */\n\nexport function randomInt(min: number, max: number): number {\n // Taken from https://stackoverflow.com/a/41452318\n if (!Number.isInteger(min) || !Number.isInteger(max))\n throw new TypeError('min and max must be integers');\n\n if (min >= max) \n throw new Error('max must be greater than min');\n\n const range = max - min + 1;\n const randomBytes = Math.ceil(Math.log2(range) / 8);\n const maxRandNumber = Math.pow(256, randomBytes);\n const randomBuffer = new Uint8Array(randomBytes);\n\n let randomValue: number;\n do {\n crypto.getRandomValues(randomBuffer);\n randomValue = 0;\n for (let index = 0; index < randomBytes; index++) {\n // eslint-disable-next-line no-bitwise\n randomValue = (randomValue << 8) + randomBuffer[index];\n }\n // rerun if randomValue is bigger than range\n } while (randomValue >= maxRandNumber - (maxRandNumber % range));\n\n return min + (randomValue % range);\n}\n","import { randomInt } from './randomInt.js';\n\n/**\n * Gets a random element an array. A single element is returned by default. \n * Specify the `multi` parameter to get an array of multiple random elements.\n *\n * If the array is empty, `undefined` is returned. \n * If `multi` is defined it returns an empty array.\n * \n * It uses `crypto.getRandomValues` to get the random element.\n * @example\n * randomElem([1, 2, 3, 4])\n * // => 2\n *\n * randomElem([1, 2, 3, 4], 2)\n * // => [3, 1]\n * @param array The array to sample.\n * @returns Returns the random element.\n */\n\nexport function randomElem<TArr>(array: TArr[]): TArr | undefined;\nexport function randomElem<TArr>(array: TArr[], multi: number): TArr[];\nexport function randomElem<TArr>(array: TArr[], multi?: number): TArr | undefined | TArr[] {\n if (multi === undefined) {\n if (array.length === 0) return undefined;\n return getSingleElement(array);\n }\n\n if (multi && array.length === 0) return [];\n\n // Multiple samples\n const result = new Array<TArr>(multi);\n for (let i = 0; i < multi; i++) {\n result[i] = getSingleElement(array);\n }\n return result;\n}\n\nfunction getSingleElement<TArr>(array: TArr[]): TArr {\n const randomIndex = randomInt(0, array.length - 1);\n return array[randomIndex];\n}","/* eslint-disable no-bitwise */\nconst shiftLeft20Bits = 2 ** 20;\nconst shiftRight52Bits = 2 ** -52;\n\n/**\n * Generates a random float between two given numbers, including those numbers.\n * \n * It uses `crypto.getRandomValues` to generate the random number.\n * @example\n * randomFloat(1, 10) \n * // => 1.123456789\n * \n * @param min The smallest float that can be generated.\n * @param max The largest float that can be generated.\n * \n * @returns A random float between `min` and `max`, including `min` and `max`.\n */\n\nexport function randomFloat(min: number, max: number): number {\n if (min >= max) {\n throw new Error('max must be greater than min');\n }\n const range = max - min;\n const randomBuffer = new Uint32Array(2);\n crypto.getRandomValues(randomBuffer);\n\n // keep all 32 bits of the the first, top 20 of the second for 52 random bits\n const mantissa = (randomBuffer[0] * shiftLeft20Bits) + (randomBuffer[1] >>> 12);\n\n // shift all 52 bits to the right of the decimal point\n const randomFloat = mantissa * shiftRight52Bits;\n return min + (randomFloat * range);\n}","import { randomInt } from './randomInt.js';\n\nconst DEFAULT_CHARSET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n\n/**\n * Generates a random string of the specified length.\n * The default charset is alphanumeric characters.\n * \n * It uses `crypto.getRandomValues` to generate the random string.\n * \n * @example\n * randomString(8);\n * // => \"JWw1p6rD\"\n *\n * randomString(16, 'abc');\n * // => \"cbaacbabcabccabc\"\n * @param length The length of the string to generate.\n * @param charSet The set of characters to use when generating the string. Defaults to alphanumeric characters.\n * @returns A random string of the specified length.\n */\n\nexport function randomString(length: number, charSet = DEFAULT_CHARSET): string {\n if (charSet.length <= 0) return '';\n\n let result = '';\n for (let index = 0; index < length; index++) {\n const randomIndex = randomInt(0, charSet.length - 1);\n result += charSet[randomIndex];\n }\n\n return result;\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\ntype Tail<T extends unknown[]> = T extends [infer _Head, ...infer Tail] ? Tail : never;\n\n/**\n * Transforms a function that takes a function as first argument into a decorator function.\n * \n * @example\n * ```typescript\n * function log(func: Function, message: string) {\n * return function (...args: unknown[]) {\n * console.log(message);\n * return func(...args);\n * };\n * }\n * \n * const logger = toDecorator(log);\n * \n * class TestClass {\n * @logger(\"Hello world!\")\n * testMethod() {\n * return 1; \n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(); \n * // => Log \"Hello World\" and return 1\n * ```\n * @param func The function to transform.\n * @returns A decorator function that can be used to decorate a method.\n */\n\nexport function toDecorator<TFunc extends GenericFunction<TFunc>>(func: TFunc) {\n return function (...args: Tail<Parameters<TFunc>>) {\n return function (target: unknown, key: string, descriptor: PropertyDescriptor) {\n const creatorArgs = [descriptor.value, ...args] as Parameters<TFunc>;\n descriptor.value = func(...creatorArgs);\n };\n };\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a debounced version of a function. Only calling it after a specified amount of time has passed without any new calls.\n * \n * **Methods:** \n * - `cancel` will cancel the next invocation of the debounced function. \n * - `flush` will immediately invoke the debounced function and cancel any pending invocations. \n * \n * This function can be used as a decorator with {@link decDebounce}.\n * \n * @example\n * const sayHello = (name: string) => console.log(`Hello, ${name}!`);\n * const debouncedSayHello = debounce(sayHello, 200);\n * \n * debouncedSayHello(\"John\");\n * debouncedSayHello(\"Jane\");\n * // => Only the second invocation of `debouncedSayHello` is executed, after a delay of 200ms.\n * @param func The function to debounce.\n * @param wait The number of milliseconds to wait before invoking `func`.\n * @returns A debounced version of `func` with `cancel` and `flush` methods.\n */\n\nexport function debounce<TFunc extends GenericFunction<TFunc>>(func: TFunc, wait: number): TFunc & {\n cancel: () => void;\n flush: () => void;\n} {\n let timeoutId: NodeJS.Timeout | undefined;\n const debounced = function (this: unknown, ...args: Parameters<TFunc>) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => func.apply(this, args), wait);\n };\n\n /** Cancels the next invocation of the debounced function. */\n debounced.cancel = function () {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n };\n\n /** Immediately invokes the debounced function and cancels any pending invocations. */\n debounced.flush = function (this: unknown, ...args: Parameters<TFunc>) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n func.apply(this, args);\n };\n\n return debounced as TFunc & { cancel: () => void; flush: () => void };\n}","import { toDecorator } from '@decorator/toDecorator.js';\nimport { debounce } from '@function/debounce.js';\n\n/**\n * Debouces the decorated function. Only calling it after a specified amount of time has passed without any new calls.\n * \n * Look at {@link debounce} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decDebounce(100)\n * testMethod(str: string) {\n * console.log(\"Debounced:\", str);\n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(\"Hello\");\n * instance.testMethod(\"World\");\n * // => Only the second invocation of `debouncedSayHello` is executed, after a delay of 1000ms.\n * ```\n * @param wait Milliseconds to wait before invoking the decorated function after the last invocation.\n */\n\nexport function decDebounce(wait: number) {\n return toDecorator(debounce)(wait);\n}\n","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a function that invokes the given function as long as it's called `<= n` times.\n * \n * Subsequent calls to the created function return the result of the last `func` invocation.\n *\n * This function can be used as a decorator with {@link decMaxCalls}.\n * @example\n * let count = 0;\n * const addCount = () => ++count;\n *\n * // Allow addCount to be invoked twice.\n * const limitAddCount = maxCalls(addCount, 2)\n *\n * limitAddCount() // => 1\n * limitAddCount() // => 2\n * limitAddCount() // => 2\n * // => `limitAddCount` is invoked twice and the result is cached.\n * @param n The number of calls before the cached result is returned.\n * @param func The function to restrict.\n * @returns Returns the new restricted function.\n */\n\nexport function maxCalls<TFunc extends GenericFunction<TFunc>>(func: TFunc, n: number): TFunc {\n let count = 0;\n let result: ReturnType<TFunc>;\n return function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> {\n if (count < n) {\n count += 1;\n result = func.apply(this, args);\n }\n return result;\n } as TFunc;\n}\n","import { toDecorator } from '@decorator/toDecorator.js';\nimport { maxCalls } from '@function/maxCalls.js';\n\n/**\n * Only invokes the decorated function as long as it's called `<= n` times. \n * Subsequent calls to the decorated function return the result of the last invocation.\n * \n * Look at {@link maxCalls} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * private count = 0;\n * @decMaxCalls(2)\n * testMethod() {\n * return ++this.count;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(); // => 1 \n * instance.testMethod(); // => 2\n * instance.testMethod(); // => 2\n * ```\n * @param n The number of calls before the cached result is returned.\n */\n\nexport function decMaxCalls(n: number) {\n return toDecorator(maxCalls)(n);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\nconst defaultResolver = (...args: unknown[]) => JSON.stringify(args);\n\n/**\n * Creates a function that memoizes the result of a given function.\n * \n * The cache key is determined by the `resolver` or by the arguments from the function call.\n *\n * **Options:**\n * - `resolver` A function that determines the cache key based on the arguments provided.\n * - `ttl` the time to live for the cache entries in milliseconds.\n * \n * **Properties:**\n * - `cache` The cache is an instance of `Map` and can be used to clear or inspect the cache. \n * It can be replaced by a custom cache that matches the `Map` interface.\n * \n * \n * This function can be used as a decorator with {@link decMemoize}.\n * \n * @example\n * ```typescript\n * function fibonacci(n: number) {\n * if (n <= 1) return n;\n * return fibonacci(n - 1) + fibonacci(n - 2);\n * }\n *\n * const memoizedFib = memoize(fibonacci, { ttl: 1000 })\n * \n * memoizedFib(40) // => 102334155\n * memoizedFib(40) // => 102334155 (cache hit)\n * setTimeout(() => memoizedFib(40), 1000) // => 102334155 (cache miss)\n * \n * // Cached values are exposed as the `cache` property.\n * memoizedFib.cache.get(\"40\") // => [value, timestamp]\n * memoizedFib.cache.set(\"40\", [1234, Date.now()])\n * memoizedFib.cache.clear()\n * \n * // This is the default way to create cache keys.\n * const defaultResolver = (...args: unknown[]) => JSON.stringify(args)\n * ```\n * @param func The function to have its output memoized.\n * @param options The options object with optional `resolver` and `ttl` parameters.\n * @param options.resolver - A function that determines the cache key for storing the result based on the arguments provided.\n * @param options.ttl - The time to live for the cache in milliseconds.\n * @template TFunc The type of the function to memoize.\n * @template Cache The type of the cache storage.\n * @returns Returns the new memoized function.\n */\n\nexport function memoize<TFunc extends GenericFunction<TFunc>, Cache extends Map<string, [ReturnType<TFunc>, number]>>(\n func: TFunc, options: { resolver?: (...args: Parameters<TFunc>) => string, ttl?: number; } = {}\n): TFunc & { cache: Cache } {\n const resolver = options.resolver ?? defaultResolver;\n const ttl = options.ttl;\n const cache = new Map() as Cache;\n\n const memoizedFunc = function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> {\n const key = resolver(...args);\n if (cache.has(key)) {\n const [cacheResult, cacheTime] = cache.get(key)!;\n if (ttl === undefined || (Date.now() - cacheTime < ttl)) {\n return cacheResult;\n }\n }\n const result = func.apply(this, args);\n cache.set(key, [result, Date.now()]);\n return result;\n };\n\n memoizedFunc.cache = cache;\n return memoizedFunc as TFunc & { cache: Cache };\n} ","import { toDecorator } from '@decorator/toDecorator.js';\nimport { memoize } from '@function/memoize.js';\n\n/**\n * Memoizes the decorated function. \n * The cache key is either determined by the provided resolver or by the arguments used in the memoized function.\n * \n * **Options:**\n * - `resolver` A function that determines the cache key for storing the result based on the arguments provided.\n * - `ttl` sets the time to live for the cache in milliseconds. After `ttl` milliseconds, the next call to the memoized function will result in a cache miss.\n * \n * Look at {@link memoize} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decMemoize({ ttl: 1000 })\n * testMethod(a: number, b: number) {\n * return a + b;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(1, 2); // => 3\n * instance.testMethod(1, 2); // => 3 (cached)\n * \n * // After 1 second:\n * instance.testMethod(1, 2); // => 3 (cache miss)\n * ```\n * @param options The options object.\n * @param options.resolver - A function that determines the cache key for storing the result based on the arguments provided.\n * @param options.ttl - The time to live for the cache in milliseconds.\n */\n\nexport function decMemoize(options: Parameters<typeof memoize>[1] = {}) {\n return toDecorator(memoize)(options);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a function that invokes the given function once it's called more than `n` times. \n * Returns undefined until the minimum call count is reached.\n * \n * This function can be used as a decorator with {@link decMinCalls}.\n * @example\n * const caution = () => console.log(\"Caution!\");\n * const limitedCaution = minCalls(caution, 2);\n *\n * limitedCaution()\n * limitedCaution()\n * limitedCaution()\n * // => `caution` is invoked on the third call.\n * @param n The number of calls before the given function is invoked.\n * @param func The function to restrict.\n * @returns Returns the new restricted function.\n */\n\nexport function minCalls<TFunc extends GenericFunction<TFunc>>(func: TFunc, n: number) {\n let count = 1;\n return function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> | undefined {\n if (count > n) {\n return func.apply(this, args);\n }\n count += 1;\n };\n}","import { toDecorator } from '@decorator/toDecorator.js';\nimport { minCalls } from '@function/minCalls.js';\n\n/** \n * Only invokes the decorated function after it's called more than `n` times.\n * \n * Look at {@link minCalls} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * @example\n * ```typescript\n * class TestClass {\n * @decMinCalls(2)\n * testMethod() {\n * return 1;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(); // => undefined\n * instance.testMethod(); // => undefined\n * instance.testMethod(); // => 1\n * ```\n * @param n The number of calls before the decorated function is invoked.\n */\n\nexport function decMinCalls(n: number) {\n return toDecorator(minCalls)(n);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Generates a function that invokes the given function at most once per every `wait` milliseconds.\n * \n * This function can be used as a decorator with {@link decThrottle}.\n * @example\n * const throttled = throttle(() => console.log(\"Throttled!\"), 1000);\n * \n * throttled();\n * throttled();\n * // => \"Throttled!\" is logged once per second.\n * @param func The function to throttle.\n * @param wait The number of milliseconds to throttle invocations to.\n * @returns Returns the new throttled function.\n */\n\n\nexport function throttle<TFunc extends GenericFunction<TFunc>>(func: TFunc, wait: number): TFunc {\n let inThrottle = false;\n return function (this: unknown, ...args: Parameters<TFunc>) {\n if (!inThrottle) {\n func.apply(this, args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), wait);\n }\n } as TFunc;\n}\n \n","import { toDecorator } from '@decorator/toDecorator.js';\nimport { throttle } from '@function/throttle.js';\n\n/**\n * The decorated function is invoked at most once per every `wait` milliseconds.\n * \n * Look at {@link throttle} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decThrottle(1000)\n * testMethod() {\n * console.log(\"Throttled!\");\n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(); // => \"Throttled!\" is logged once per second.\n * instance.testMethod(); // nothing happens\n * ```\n * @param wait The number of milliseconds to wait between invocations.\n */\n\nexport function decThrottle(wait: number) {\n return toDecorator(throttle)(wait);\n}","/**\n * Invokes a function `n` times, returning an array of the results of\n * each invocation.\n * \n * @example\n * times(index => console.log(\"Run\", index), 3)\n * // => \"Run 0\" | \"Run 1\" | \"Run 2\"\n * times(Math.random, 3)\n * // => [0.123, 0.456, 0.789]\n * times(() => 0, 4)\n * // => [0, 0, 0, 0]\n * @param n The number of times to invoke `func`.\n * @param func The function invoked per iteration.\n * @returns Returns an array of results.\n */\n\nexport function times<TInput>(func: (index: number) => TInput, n: number): TInput[] {\n const result: TInput[] = [];\n for (let i = 0; i < n; i++) {\n result.push(func(i));\n }\n return result;\n}","/**\n * Calculates the sum of an array of numbers.\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * sum([1, 2, 3, 4, 5]) // => 15\n * \n * @param numbers The input array of numbers\n * @returns The sum of the input array \n */\n\nexport function sum(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n return numbers.reduce((total, current) => total + current, 0);\n}","import { sum } from '@number/sum.js';\n\n/**\n * Calculates the average of an array of numbers\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * average([1, 2, 3, 4, 5]) // => 3\n * \n * @param numbers The input array of numbers\n * @returns The average of the input array, or NaN if the input array is empty\n */\n\nexport function average(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n return sum(numbers) / numbers.length;\n}","/**\n * Calculates the median of an array of numbers\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * median([1, 2, 3, 4, 5]) // => 3\n * median([1, 2, 3, 4, 5, 6]) // => 3.5\n * \n * @param numbers The input array of numbers\n * @returns The median of the input array\n */\n\nexport function median(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n const sortedArray = [...numbers].sort((a, b) => a - b);\n const mid = Math.floor(sortedArray.length / 2);\n return sortedArray.length % 2 === 0 ? ((sortedArray[mid - 1] + sortedArray[mid]) / 2) : sortedArray[mid];\n}","/**\n * Rounds a number to the given precision.\n *\n * @example\n * round(1.23456, 2); // => 1.23\n * round(1.235, 1); // => 1.2\n * round(1234.56); // => 1234.56\n * \n * @param number The number to be rounded.\n * @param precision The number of decimal places to round to. Defaults to 2.\n * @returns The rounded number.\n */\n\nexport function round(number: number, precision = 2): number {\n const factor = Math.pow(10, precision);\n return Math.round((number + Number.EPSILON) * factor) / factor;\n}","import type { PlainObject } from '@type/PlainObject.js';\n\n/**\n * Checks if the value is a plain object.\n * \n * @example\n * isPlainObject({}) // => true\n * isPlainObject({ a: 1 }) // => true\n * isPlainObject(null) // => false\n * isPlainObject('1') // => false\n * isPlainObject([]) // => false\n * isPlainObject(new Function()) // => false\n * isPlainObject(new Date()) // => false\n * @param value The value to check\n * @returns Boolean indicating if the value is a plain object\n */\n\nexport function isPlainObject(value: unknown): value is PlainObject {\n return value?.constructor === Object;\n}","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\n/**\n * Flattens an object into a single level object.\n * \n * @example\n * const obj = { a: { b: 2, c: [{ d: 3 }, {d: 4 }] } };\n * flatKeys(obj);\n * // => { 'a.b': 2, 'a.c[0].d': 3, 'a.c[1].d': 4 }\n * \n * @param obj The object to flatten.\n * @template TObj The type of the object to flatten.\n * @returns A new object with flattened keys.\n */\n\nexport function flatKeys<TObj extends PlainObject>(obj: TObj): Record<string, unknown> {\n const flatObject: Record<string, unknown> = {};\n \n for (const [key, value] of Object.entries(obj)) {\n addToResult(key, value, flatObject);\n }\n \n return flatObject;\n}\n\nfunction addToResult(prefix: string, value: unknown, flatObject: Record<string, unknown>) {\n if (isPlainObject(value)) {\n const flatObj = flatKeys(value);\n for (const [flatKey, flatValue] of Object.entries(flatObj)) {\n flatObject[`${prefix}.${flatKey}`] = flatValue;\n }\n } else if (Array.isArray(value)) {\n for (const [index, element] of value.entries()) {\n addToResult(`${prefix}[${index}]`, element, flatObject);\n }\n\n } else {\n flatObject[prefix] = value;\n }\n}","import type { ArrayMinLength } from '@type/ArrayMinLength.js';\nimport type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\n/**\n * This function combines two or more objects into a single new object. Arrays and other types are overwritten.\n * \n * @example\n * // ---- Nested objects are merged ----\n * merge({ a: 1 }, { b: 2 }, { c: 3, d: { e: 4 } }) \n * // => { a: 1, b: 2, c: 3, d: { e: 4 } }\n *\n * // ---- Other types are overwritten ----\n * merge({ a: [1, 2] }, { a: [3, 4] })\n * // => { a: [3, 4] }\n * \n * merge({ a: 1 }, { a: \"Yes\" })\n * // => { a: \"Yes\" }\n * @param target The target object\n * @param sources The source objects\n * @template TTarget The type of the target object\n * @template TSources The type of the source objects\n * @returns A new merged object\n */\n\nexport function merge<TTarget extends PlainObject, TSources extends ArrayMinLength<PlainObject, 1>>(target: TTarget, ...sources: TSources): MergeDeepObjects<[TTarget, ...TSources]> {\n const targetCopy = { ...target };\n for (const source of sources) {\n for (const [key, value] of Object.entries(source)) {\n (targetCopy as PlainObject)[key] = isPlainObject(value) && isPlainObject(targetCopy[key]) \n ? merge(targetCopy[key] as PlainObject, value) \n : value;\n }\n }\n return targetCopy as MergeDeepObjects<[TTarget, ...TSources]>; \n}\n\ntype OptionalPropertyNames<T> =\n { [K in keyof T]-?: (PlainObject extends { [P in K]: T[K] } ? K : never) }[keyof T];\n\ntype SpreadProperties<L, R, K extends keyof L & keyof R> =\n { [P in K]: L[P] | Exclude<R[P], undefined> };\n\ntype Id<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;\n\ntype SpreadTwo<L, R> = Id<\n& Pick<L, Exclude<keyof L, keyof R>>\n& Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>>\n& Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>>\n& SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>\n>;\n\ntype MergeDeepObjects<A extends readonly [...unknown[]]> = A extends [infer L, ...infer R] ?\n SpreadTwo<L, MergeDeepObjects<R>> : unknown;\n","import type { PlainObject } from '@type/PlainObject.js';\n\n/**\n * Creates an object composed of the picked `object` properties.\n *\n * @example\n * const object = { 'a': 1, 'b': '2', 'c': 3 }\n *\n * pick(object, ['a', 'c'])\n * // => { 'a': 1, 'c': 3 }\n * @param object The source object.\n * @param keysToPick The property paths to pick.\n * @template TObj The type of the object.\n * @returns Returns the new object.\n */\n\nexport function pick<TObj extends PlainObject, Key extends keyof TObj>(object: TObj, keysToPick: Key[]): Pick<TObj, Key> {\n const result = {} as Pick<TObj, Key>;\n for (const key of keysToPick) {\n result[key] = object[key];\n }\n return result;\n}\n","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { pick } from './pick.js';\n\n/**\n * Omit specified keys from an object\n *\n * @example\n * const obj = {a: 1, b: 2, c: 3};\n * omit(obj, ['a', 'b']);\n * // => {c: 3}\n *\n * @param object The object to filter\n * @param keysToOmit The keys to exclude from the returned object\n * @template TObj The type of the object\n * @returns - An object without the specified keys\n */\n\nexport function omit<TObj extends PlainObject, Key extends keyof TObj>(object: TObj, keysToOmit: Key[]): Omit<TObj, Key> {\n const keys = Object.keys(object);\n const filteredKeys = keys.filter(key => !keysToOmit.includes(key as Key)) as Exclude<keyof TObj, Key>[];\n\n return pick(object, filteredKeys);\n}","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\nconst validPathRegex = /^(?:[^.[\\]]+(?:\\[\\d+])*(?:\\.|\\[\\d+]))+(?:[^.[\\]]+(?:\\[\\d+])*)+$/;\nconst pathSplitRegex = /\\.|(?=\\[)/g;\nconst matchBracketsRegex = /[[\\]]/g;\n\n/**\n * Sets the value at path of object. If a portion of path doesn’t exist, it’s created.\n * \n * @example\n * const obj = { a: { b: 2 } };\n * set(obj, 'a.c', 1);\n * // => { a: { b: 2, c: 1 } }\n * \n * // `[number]` can be used to access array elements\n * set(obj, 'a.c[0]', 'hello');\n * // => { a: { b: 2, c: ['hello'] } }\n * \n * // numbers with dots are treated as keys\n * set(obj, 'a.c.0.d', 'world');\n * // => { a: { b: 2, c: { 0: { d: 'world' } } }\n * \n * // supports numbers in keys\n * set(obj, 'a.e0.a', 1);\n * // => { a: { e0: { a: 1 } } }\n * \n * @param obj The object to modify.\n * @param path The path of the property to set.\n * @param value The value to set.\n * @template TObj The type of the object.\n * @returns The modified object.\n */\n\nexport function set(obj: PlainObject, path: string, value: unknown): PlainObject {\n if (!validPathRegex.test(path))\n throw new Error('Invalid path, look at the examples for the correct format.');\n\n const pathParts = path.split(pathSplitRegex);\n let currentObj: PlainObject = obj;\n for (let index = 0; index < pathParts.length; index++) {\n const key = pathParts[index].replace(matchBracketsRegex, '');\n\n if (index === pathParts.length - 1) {\n currentObj[key] = value;\n break;\n }\n\n const nextElemIn = pathParts[index + 1].startsWith('[') ? 'array' : 'object';\n if (currentObj[key] === undefined) {\n currentObj[key] = nextElemIn === 'array' ? [] : {};\n } else if (nextElemIn === 'array' && !Array.isArray(currentObj[key])) {\n currentObj[key] = [];\n } else if (nextElemIn === 'object' && !isPlainObject(currentObj[key])) {\n currentObj[key] = {};\n }\n currentObj = currentObj[key] as PlainObject;\n }\n\n return obj;\n}","/**\n * A class for managing a queue of async functions that runs a set number concurrently. \n * If for example you have 10 async functions and you want to run 3 at a time, you can use this class.\n * \n * If the queue is paused, the queue will not run any more async functions until it is resumed.\n * \n * **Methods:**\n * - `add` - adds a async function or array of functions to the queue. Returns a promise that resolves when the added function(s) finish.\n * - `clear` - clears the queue.\n * - `pause` - pauses the queue.\n * - `resume` - resumes the queue. \n * - `getQueue` - returns the current queue.\n * - `isPaused` - returns whether the queue is paused.\n * \n * @example\n * // Create a queue that can run 3 tasks concurrently\n * const queue = new Queue(3);\n * \n * queue.add(() => fetch('https://example.com'));\n * \n * queue.add(async () => {\n * const response = await fetch('https://example.com');\n * return response.json();\n * });\n * \n * // Add an array of tasks to the queue and wait for them to resolve\n * await queue.add([\n * () => fetch('https://apple.com'),\n * () => fetch('https://microsoft.com')\n * ]);\n * // => [Response, Response]\n */\n\nexport class Queue {\n private running = 0;\n private maxConcurrent: number;\n private paused = false;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private queue: { asyncFn: () => Promise<any>, resolve: (value: any) => void, reject: (reason?: any) => void }[] = [];\n\n /**\n * @constructor\n * @param maxConcurrent The maximum number of async functions to run concurrently.\n */\n constructor(maxConcurrent: number) {\n this.maxConcurrent = maxConcurrent;\n }\n\n /**\n * Add aync functions or an array of async functions to the queue.\n * \n * @param asyncFn The aync function(s) to add to the queue.\n * @returns A promise that resolves when the added function(s) finishes.\n */\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn): Promise<TProm>;\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn[]): Promise<TProm[]>;\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn | TAsyncFn[]): Promise<TProm> | Promise<TProm[]> {\n if (Array.isArray(asyncFn)) {\n const promises = asyncFn.map((fn) => this.buildWaitingPromise(fn));\n return Promise.all(promises);\n } else {\n return this.buildWaitingPromise(asyncFn);\n } \n }\n\n private buildWaitingPromise<TProm>(asyncFn: () => Promise<TProm>): Promise<TProm> {\n return new Promise((resolve, reject) => {\n this.queue.push({ asyncFn, resolve, reject });\n this.run();\n });\n } \n\n private run() {\n while (this.queue.length > 0 && this.running < this.maxConcurrent && !this.paused) {\n this.running++;\n const queueElement = this.queue.shift()!;\n void queueElement.asyncFn()\n .then((result) => {\n queueElement.resolve(result);\n }).catch((error) => {\n queueElement.reject(error);\n }).finally(() => {\n this.running--;\n this.run();\n });\n }\n }\n\n /** Removes all the tasks from the queue */\n clear() {\n for (const queueElement of this.queue) {\n queueElement.reject(new Error('Queue cleared'));\n }\n this.queue = [];\n }\n\n /** Pauses the execution of the queue */\n pause() {\n this.paused = true;\n }\n\n /** Resumes the execution of the tasks in the queue */\n resume() {\n this.paused = false;\n this.run();\n }\n\n /** Return the tasks added to the queue */\n getQueue() {\n return this.queue.map((queueElement) => queueElement.asyncFn);\n }\n\n /** Returns whether the queue is paused */\n isPaused() {\n return this.paused;\n }\n\n}\n","/**\n * Similar to [Promise.race](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race?retiredLocale=de) \n * but allows to specify how many promises to wait for.\n *\n * @example\n * const prom1 = Promise.resolve(1);\n * const prom2 = new Promise(resolve => setTimeout(resolve, 100, 2));\n * const prom3 = Promise.resolve(3);\n * \n * const firstTwo = await races(2, prom1, prom2, prom3);\n * // => [1, 3]\n * \n * @template TRes The type of the result of the promises.\n * @param waitFor The number of promises to wait for.\n * @param promises The promises to wait for.\n * @returns A promise that resolves an array of the results of the first n promises.\n */\n\nexport function races<TRes>(waitFor: number, ...promises: Promise<TRes>[]): Promise<TRes[]> {\n return new Promise((resolve, reject) => {\n if (promises.length < waitFor)\n waitFor = promises.length;\n\n const results: TRes[] = [];\n let resolved = 0;\n for (const promise of promises) {\n promise.then((value) => {\n results.push(value);\n resolved++;\n if (resolved >= waitFor) {\n resolve(results);\n }\n }).catch((error) => {\n reject(error);\n });\n }\n });\n}","/**\n * Sleeps for the given amount of time.\n *\n * @example\n * await sleep(1000);\n * // => Waits for 1 second.\n * @param ms Amount of time to sleep in milliseconds.\n * @returns A promise that resolves after the given amount of time.\n */\nexport function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}","/* eslint-disable no-await-in-loop */\nimport { sleep } from '@promise/sleep.js';\n\n/**\n * Retry a function until it succeeds or the maximum number of retries is reached.\n * \n * Default maxRetries: `5`. \n * Default backoff: `2^retries * 100ms` (100, 200, 400, 800, 1600, 3200, ...)\n *\n * @example\n * await retry(() => fetch('https://example.com'));\n * \n * // ---- Advanced example ----\n * const fetchSite = async () => {\n * const response = await fetch('https://example.com');\n * if(!response.ok)\n * throw new Error('Failed to fetch');\n * }\n * \n * const logger = (error: unknown, retry?: number) => console.log(\"Retrying\", retry, error);\n * \n * await retry(fetchSite, { maxRetries: 3, backoff: retries => retries * 1000, onRetry: logger });\n * // => Will retry 3 times with a 1 second delay between each retry.\n * // => Will log the error and retry number.\n * \n * @param func The function to retry.\n * @param options The options for the retry.\n * @param options.maxRetries The maximum number of retries. Defaults to `5`.\n * @param options.backoff The backoff function to use. Defaults to `2^retries * 100`.\n * @param options.onRetry The function to call when a retry is attempted. It will be called with the error and the attempt number.\n * @template TRes The type of the result of the function.\n * @returns A promise that resolves when the function succeeds.\n */\n\nexport async function retry<TRes>(\n func: () => Promise<TRes>, \n options?: { \n maxRetries?: number,\n backoff?: ((retries: number) => number),\n onRetry?: (error?: unknown, attempted?: number) => void\n }\n): Promise<TRes> {\n const backOffFn = options?.backoff ?? (retries => (2 ** retries) * 100);\n const maxRetries = options?.maxRetries ?? 5;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n const onRetry = options?.onRetry ?? (() => {});\n let retries = 0;\n let lastError: unknown;\n\n while (retries <= maxRetries) {\n try {\n if (retries > 0)\n onRetry(lastError, retries);\n return await func();\n } catch (error) {\n lastError = error;\n retries++;\n if (retries > maxRetries) {\n throw error;\n }\n await sleep(backOffFn(retries));\n }\n /* c8 ignore next 2 */\n }\n throw new Error('Retry terminated without success, this should never happen');\n}","/**\n * Returns a new promise that will reject with an error after a specified timeout. \n *\n * @example\n * try {\n * await timeout(fetch('https://example.com'), 1000);\n * } catch (error) {\n * console.log(error.message);\n * // => 'Promise timed out after 1000ms'\n * }\n * @template TRes - The type of the resolved value.\n * @param promise The promise to wrap.\n * @param timeout The timeout in milliseconds.\n * \n * @returns A new promise that will reject with an error after the specified timeout.\n */\nexport function timeout<TRes>(promise: Promise<TRes>, timeout: number): Promise<TRes> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error(`Promise timed out after ${timeout}ms`));\n }, timeout);\n \n promise.then(\n (result) => {\n clearTimeout(timeoutId);\n resolve(result);\n },\n (error) => {\n clearTimeout(timeoutId);\n reject(error);\n }\n );\n });\n}","/**\n * Attempts to execute a promise and returns an array with the result or error.\n * \n * This is useful for handling errors in async functions without try/catch blocks.\n * \n * @example\n * ```typescript\n * const [data, error] = await tryCatch(fetch('https://example.com/api'));\n * if (error)\n * console.error(`Error: ${error.message}`);\n * ```\n * @param promise A Promise to be executed.\n * @returns A Promise that resolves to an array containing the result or error. \n * If the Promise executes successfully, the array contains the result and a null error. \n * If the Promise throws an error, the array contains undefined for the result and the error object.\n *\n * @template TRes The type of the result.\n */\n\nexport async function tryCatch<TRes>(promise: Promise<TRes>): Promise<[TRes, undefined] | [undefined, Error]> {\n try {\n const data = await promise;\n return [data, undefined];\n } catch (error) {\n if (error instanceof Error)\n return [undefined, error];\n\n throw error;\n }\n}","// Split non-alphanumeric characters with spaces and deal with camel/PascalCase\nconst splitWordsRegex = new RegExp(\n '[^\\\\dA-Za-z]' + // match any character that is not a letter or a digit\n '|' + // or\n '(?<=[a-z])' + // lookbehind for a lowercase letter\n '(?=[A-Z])' + // lookahead for an uppercase letter\n '|' + // or\n '(?<=[A-Z])' + // lookbehind for an uppercase letter\n '(?=[A-Z][a-z])' // lookahead for an uppercase letter followed by a lowercase letter\n);\n\n/**\n * Split a string into words. Can deal with camelCase, PascalCase & snake_case.\n * \n * @example\n * splitWords('camelCase')\n * // => ['camel', 'Case']\n * \n * splitWords('PascalCase')\n * // => ['Pascal', 'Case']\n * \n * splitWords('hello_world-123')\n * // => ['hello', 'world', '123']\n * \n * @param str The string to split into words.\n * @returns An array of words.\n */\n\nexport function splitWords(str: string): string[] {\n return str.split(splitWordsRegex).filter(Boolean);\n}","const accentControlRegex = /[\\u0300-\\u036F]/g;\n\n/**\n * Deburrs a string by converting\n * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n * letters to basic Latin letters and removing\n * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n *\n * @example\n * deburr('déjà vu')\n * // => 'deja vu'\n * @param str The string to deburr.\n * @returns Returns the deburred string.\n */\n\nexport function deburr(str: string): string {\n return str.normalize('NFD').replace(accentControlRegex, '');\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts `string` to camelCase.\n *\n * @example\n * camelCase('Foo Bar')\n * // => 'fooBar'\n * camelCase('--foo-bar--')\n * // => 'fooBar'\n * camelCase('__FOO_BAR__')\n * // => 'fooBar'\n * @param str The string to convert.\n * @returns Returns the camel cased string.\n */\n\nexport function camelCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n\n // Capitalize the first letter of each word\n const camelCase = words.map((word: string, index: number) => {\n if (index === 0) {\n return word.toLowerCase();\n }\n return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n });\n\n return camelCase.join('');\n}\n","/**\n * Converts the first character of a string to upper case and the remaining to lower case.\n *\n * @example\n * capitalize('FRED')\n * // => 'Fred'\n * @param str The string to capitalize.\n * @returns Returns the capitalized string.\n */\n\nexport function capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","const charRegex = /[\"&'<>]/g;\nconst escapeChars = new Map([\n ['&', '&amp;'],\n ['<', '&lt;'],\n ['>', '&gt;'],\n ['\\'', '&#39;'],\n ['\"', '&quot;']\n]);\n\n/**\n * Converts the characters `&`, `<`, `>`, `\"` and `'` in a string to their corresponding HTML entities.\n *\n * @example\n * escapeHtml('fred, barney, & pebbles')\n * // => 'fred, barney, &amp; pebbles'\n * @param str The string to escape.\n * @returns Returns the escaped string.\n */\n\nexport function escapeHtml(str: string): string {\n return str.replace(charRegex, char => escapeChars.get(char)!);\n}\n","const escapleCharsRegex = /[$()*+.?[\\\\\\]^{|}]/g;\n\n/**\n * Escapes the `RegExp` special characters `^`, `$`, `\\`, `.`, `*`, `+`,\n * `?`, `(`, `)`, `[`, `]`, `{`, `}`, and `|` in a string.\n *\n * @example\n * escapeRegExp('[moderndash](https://moderndash.io/)')\n * // => '\\[moderndash\\]\\(https://moderndash\\.io/\\)'\n * @param str The string to escape.\n * @returns Returns the escaped string.\n */\n\nexport function escapeRegExp(str: string): string {\n return str.replace(escapleCharsRegex, '\\\\$&');\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to kebab-case.\n *\n * @example\n * kebabCase('Foo Bar')\n * // => 'foo-bar'\n * kebabCase('fooBar')\n * // => 'foo-bar'\n * kebabCase('__FOO_BAR__')\n * // => 'foo-bar'\n * \n * @param str The string to convert.\n * @returns Returns the kebab cased string.\n */\n\nexport function kebabCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let kebabCase = '';\n for (const word of words) {\n kebabCase += word.toLowerCase() + '-';\n }\n return kebabCase.slice(0, -1);\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n\n/**\n * Converts a string to PascalCase.\n *\n * @example\n * pascalCase('Foo Bar')\n * // => 'FooBar'\n * pascalCase('fooBar')\n * // => 'FooBar'\n * pascalCase('__FOO_BAR__')\n * // => 'FooBar'\n * \n * @param str The string to convert.\n * @returns Returns the pascal cased string.\n */\n\nexport function pascalCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let pascalCase = '';\n for (const word of words) {\n pascalCase += word.charAt(0).toUpperCase() + word.slice(1);\n }\n return pascalCase;\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to snake_case.\n *\n * @example\n * snakeCase('Foo Bar')\n * // => 'foo_bar'\n * snakeCase('fooBar')\n * // => 'foo_bar'\n * snakeCase('--FOO-BAR--')\n * // => 'foo_bar'\n * snakeCase('foo2bar')\n * // => 'foo_2_bar'\n * \n * @param str The string to convert.\n * @returns Returns the snake cased string.\n */\n\nexport function snakeCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let snakeCase = '';\n for (const word of words) {\n if (snakeCase.length > 0) {\n snakeCase += '_';\n }\n snakeCase += word.toLowerCase();\n }\n return snakeCase;\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to Title Case.\n *\n * @example\n * titleCase('--foo-bar--')\n * // => 'Foo Bar'\n * titleCase('fooBar')\n * // => 'Foo Bar'\n * titleCase('__FOO_BAR__')\n * // => 'Foo Bar'\n * titleCase('HélloWorld')\n * // => 'Hello World'\n * @param str The string to convert.\n * @returns Returns the title cased string.\n */\n\nexport function titleCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let titleCase = '';\n for (const word of words) {\n titleCase += word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() + ' ';\n }\n return titleCase.trimEnd();\n}\n","const htmlEntitiesRegex = /&(?:amp|lt|gt|quot|#39);/g;\nconst entityMap = new Map([\n ['&amp;', '&'],\n ['&lt;', '<'],\n ['&gt;', '>'],\n ['&quot;', '\"'],\n ['&#39;', '\\'']\n]);\n\n/**\n * Converts the HTML entities `&amp;`, `&lt;`, `&gt;`, `&quot;` and `&#39;`\n * in a string to their corresponding characters.\n *\n * @example\n * unescapeHtml('fred, barney, &amp; pebbles')\n * // => 'fred, barney, & pebbles'\n * @param str The string to unescape.\n * @returns Returns the unescaped string.\n */\n\nexport function unescapeHtml(str: string): string {\n return str.replace(htmlEntitiesRegex, (entity: string) => entityMap.get(entity)!);\n}\n","/**\n * Checks if `value` is an empty object, collection, map, or set.\n *\n * @example\n * isEmpty(null)\n * // => true\n *\n * isEmpty({})\n * // => true\n *\n * isEmpty(\"\")\n * // => true\n *\n * isEmpty([1, 2, 3])\n * // => false\n *\n * isEmpty('abc')\n * // => false\n *\n * isEmpty({ 'a': 1 })\n * // => false\n * @param value The value to check.\n * @returns Returns `true` if given vlaue is empty, else `false`.\n */\n\nexport function isEmpty(value: string | object | null | undefined): boolean {\n if (value === null || value === undefined) {\n return true;\n }\n\n if (typeof value === 'string' || Array.isArray(value)) {\n return value.length === 0;\n }\n\n if (value instanceof Map || value instanceof Set) {\n return value.size === 0;\n }\n\n if (typeof value === 'object') {\n return Object.keys(value).length === 0;\n }\n\n return false;\n}\n","/* eslint-disable complexity */\nimport type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from './isPlainObject.js';\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * @example\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n * @param a The value to compare.\n * @param b The other value to compare.\n * @returns Returns `true` if the values are equivalent, else `false`.\n */\n\nexport function isEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n \n if (typeof a !== typeof b) return false;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return isSameArray(a, b);\n }\n\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.toString() === b.toString();\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n return isSameObject(a, b);\n }\n\n return false;\n}\n\nfunction isSameObject(a: PlainObject, b: PlainObject) {\n // check if the objects have the same keys\n const keys1 = Object.keys(a);\n const keys2 = Object.keys(b);\n if (!isEqual(keys1, keys2)) return false;\n\n // check if the values of each key in the objects are equal\n for (const key of keys1) {\n if (!isEqual(a[key], b[key])) return false;\n }\n\n // the objects are deeply equal\n return true;\n}\n\nfunction isSameArray(a: unknown[], b: unknown[]) {\n if (a.length !== b.length) return false;\n\n // check if the values of each element in the arrays are equal\n for (const [i, element] of a.entries()) {\n if (!isEqual(element, b[i])) return false;\n }\n\n return true;\n}\n","/**\n * Checks if given string is a valid URL\n *\n * @example\n * isUrl('https://google.com')\n * // => true\n * isUrl('google.com')\n * // => false\n * @param str The string to check.\n * @returns Returns `true` if given string is a valid URL, else `false`.\n */\n\nexport function isUrl(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return false;\n }\n}"],"mappings":"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","names":["difference","intersection","range","range","randomFloat","count","count","retries","timeout","camelCase","kebabCase","pascalCase","snakeCase","titleCase"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/array/chunk.ts","../src/array/count.ts","../src/helpers/fastArrayFlat.ts","../src/array/difference.ts","../src/array/dropRightWhile.ts","../src/array/dropWhile.ts","../src/array/group.ts","../src/array/unique.ts","../src/array/intersection.ts","../src/array/range.ts","../src/array/shuffle.ts","../src/array/sort.ts","../src/array/takeRightWhile.ts","../src/array/takeWhile.ts","../src/crypto/hash.ts","../src/crypto/randomInt.ts","../src/crypto/randomElem.ts","../src/crypto/randomFloat.ts","../src/crypto/randomString.ts","../src/decorator/toDecorator.ts","../src/function/debounce.ts","../src/decorator/decDebounce.ts","../src/function/maxCalls.ts","../src/decorator/decMaxCalls.ts","../src/function/memoize.ts","../src/decorator/decMemoize.ts","../src/function/minCalls.ts","../src/decorator/decMinCalls.ts","../src/function/throttle.ts","../src/decorator/decThrottle.ts","../src/function/times.ts","../src/number/sum.ts","../src/number/average.ts","../src/number/median.ts","../src/number/round.ts","../src/validate/isPlainObject.ts","../src/object/flatKeys.ts","../src/object/merge.ts","../src/object/pick.ts","../src/object/omit.ts","../src/object/set.ts","../src/promise/queue.ts","../src/promise/races.ts","../src/promise/sleep.ts","../src/promise/retry.ts","../src/promise/timeout.ts","../src/promise/tryCatch.ts","../src/string/splitWords.ts","../src/string/deburr.ts","../src/string/camelCase.ts","../src/string/capitalize.ts","../src/string/escapeHtml.ts","../src/string/escapeRegExp.ts","../src/string/kebabCase.ts","../src/string/pascalCase.ts","../src/string/snakeCase.ts","../src/string/titleCase.ts","../src/string/unescapeHtml.ts","../src/validate/isEmpty.ts","../src/validate/isEqual.ts","../src/validate/isUrl.ts"],"sourcesContent":["export * from './array';\nexport * from './crypto';\nexport * from './decorator';\nexport * from './function';\nexport * from './number';\nexport * from './object';\nexport * from './promise';\nexport * from './string';\nexport * from './type';\nexport * from './validate';\n","/**\n * Creates an array of elements split into groups the length of size. If array can't be split evenly, the final chunk will be the remaining elements.\n *\n * @example\n * chunk(['a', 'b', 'c', 'd'], 2)\n * // => [['a', 'b'], ['c', 'd']]\n *\n * chunk(['a', 'b', 'c', 'd'], 3)\n * // => [['a', 'b', 'c'], ['d']]\n * @param chunkSize The length of each chunk\n * @param array The array to chunk.\n * @template TElem The type of the array elements.\n * @returns Returns the new array of chunks.\n */\n\nexport function chunk<TElem>(array: readonly TElem[], chunkSize: number): TElem[][] {\n const intSize = Math.trunc(chunkSize);\n if (array.length === 0 || intSize < 1) {\n return [];\n }\n \n let index = 0;\n let resultIndex = 0;\n const result = new Array(Math.ceil(array.length / intSize)) as TElem[][];\n\n while (index < array.length) {\n result[resultIndex++] = array.slice(index, (index += intSize));\n }\n\n return result;\n}\n","/**\n * Creates an object with counts of occurrences of items in the array.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true, age: 36 },\n * { 'user': 'betty', 'active': false, age: 36 },\n * { 'user': 'fred', 'active': true, age: 40 }\n * ]\n *\n * count(users, value => value.active ? 'active' : 'inactive');\n * // => { 'active': 2, 'inactive': 1 }\n *\n * count(users, value => value.age);\n * // => { 36: 2, 40: 1 }\n *\n * @param criteria The criteria to count by.\n * @param array The array or record to iterate over.\n * @template TElem The type of the array elements.\n * @returns Returns the composed aggregate object.\n */\n\nexport function count<TElem, TKey extends PropertyKey>(array: readonly TElem[], criteria: (value: TElem) => TKey): Record<TKey, number> {\n const result = {} as Record<TKey, number>;\n for (const value of array) {\n const key = criteria(value);\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n result[key] = (result[key] ?? 0) + 1;\n }\n return result;\n}","// native array.flat is much slower than this - node 19\nexport function fastArrayFlat<TElem>(arrays: (readonly TElem[])[]): readonly TElem[] {\n let result = arrays.shift() ?? [];\n\n for (const array of arrays) {\n result = [...result, ...array];\n }\n\n return result;\n}","import type { CompareFunction } from '@helpers/ArrayTypeUtils.js';\nimport type { ArrayMinLength } from '@type/ArrayMinLength.js';\n\nimport { fastArrayFlat } from '@helpers/fastArrayFlat.js';\n\n/**\n * Create a new array with values from the first array that are not present in the other arrays.\n * \n * Optionally, use a compare function to determine the comparison of elements (default is `===`).\n * \n * @example\n * difference([2, 1], [2, 3], [6])\n * // => [1]\n *\n * // ---- Custom compare function ----\n * const compareByFloor = (a, b) => Math.floor(a) === Math.floor(b);\n * difference([1.2, 3.1], [1.3, 2.4], compareByFloor)\n * // => [3.1]\n *\n * // ---- Only compare by id ----\n * const arr1 = [{ id: 1, name: 'Yeet' }, { id: 3, name: 'John' }];\n * const arr2 = [{ id: 3, name: 'Carl' }, { id: 4, name: 'Max' }];\n *\n * difference(arr1, arr2, (a, b) => a.id === b.id)\n * // => [{ id: 1, name: 'Yeet' }]\n * @param arraysOrCompareFn Two or more arrays with an optional compare function at the end.\n * @template TElem The type of the array elements.\n * @template TArrays The type of the arrays provided.\n * @returns Returns the new array of filtered values.\n */\n\nexport function difference<TElem>(...arraysOrCompareFn: ArrayMinLength<TElem[], 2>): TElem[];\nexport function difference<TArrays extends ArrayMinLength<unknown[], 2>>(...arraysOrCompareFn: [...TArrays, CompareFunction<TArrays>]): TArrays[0];\nexport function difference<TArrays extends ArrayMinLength<unknown[], 2>, TElem>(...arraysOrCompareFn: ArrayMinLength<TElem[], 2> | [...TArrays, CompareFunction<TArrays>]): TArrays[0] {\n const compareFnProvided = typeof arraysOrCompareFn.at(-1) === 'function';\n const compareFunction = compareFnProvided && arraysOrCompareFn.pop() as CompareFunction<TArrays>;\n\n const arrays = arraysOrCompareFn as TArrays;\n const firstArray = arrays.shift()!;\n const combinedRestArray = fastArrayFlat(arrays);\n\n if (!compareFunction) {\n const restSet = new Set(combinedRestArray);\n return firstArray.filter(element => !restSet.has(element));\n }\n\n const difference: TArrays[0] = [];\n for (const element of firstArray) {\n if (combinedRestArray.every(item => !compareFunction(element, item))) {\n difference.push(element);\n }\n }\n\n return difference;\n}","/**\n * Creates a slice of `array` excluding elements dropped from the end. \n * Elements are dropped until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': true }\n * ]\n *\n * dropRightWhile(users, user => user.active)\n * // => objects for ['barney']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function dropRightWhile<TElem>(array: readonly TElem[], predicate: (value: TElem) => boolean) {\n let i = array.length;\n while (i > 0 && predicate(array[i - 1])) {\n i--;\n }\n return array.slice(0, i);\n}\n","/**\n * Creates a slice of `array` excluding elements dropped from the beginning. \n * Elements are dropped until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': false }\n * ]\n *\n * dropWhile(users, user => user.active)\n * // => objects for ['pebbles']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function dropWhile<TElem>(array: readonly TElem[], predicate: (value: TElem) => boolean): TElem[] {\n const index = array.findIndex(x => !predicate(x));\n return array.slice(index === -1 ? array.length : index);\n}\n","/**\n * Creates an object with grouped items in the array.\n *\n * @example\n * group([6.1, 4.2, 6.3], Math.floor)\n * // => { 4: [4.2], 6: [6.1, 6.3] }\n *\n * group([6.1, 4.2, 6.3], value => value > 5 ? '>5' : '<=5')\n * // => { '<=5': [4.2], '>5': [6.1, 6.3] }\n * \n * @param collection The array or object to iterate over.\n * @param getGroupKey A function that returns the group id for each item.\n * @template TElem The type of the array elements.\n * @returns An object with grouped items.\n */\n\nexport function group<TElem, TKey extends PropertyKey>(array: readonly TElem[], getGroupKey: (elem: TElem) => TKey): Record<TKey, TElem[]> {\n const result = {} as Record<TKey, TElem[]>;\n for (const elem of array) {\n const key = getGroupKey(elem);\n (result[key] ??= []).push(elem);\n }\n return result;\n}","/**\n * Creates a duplicate-free version of an array, in which only the first occurrence of each element is kept. \n * The order of result values is determined by the order they occur in the array.\n *\n * A compare function is optional to specify how the array is compared (default is `===`).\n * \n * @example\n * unique([2, 1, 2])\n * // => [2, 1]\n * \n * // compare by object values\n * const users = [\n * { id: 1, name: 'john' },\n * { id: 2, name: 'john' },\n * { id: 2, name: 'john' },\n * ]\n * \n * unique(users, isEqual)\n * // => [{ id: 1, name: 'john' }, { id: 2, name: 'john' }]\n * \n * // compare by id\n * unique(users, (a, b) => a.name === b.name)\n * // => [{ id: 1, name: 'john' }]\n *\n * @param array The array to inspect.\n * @param iteratee The iteratee invoked per element.\n * @template TElem The type of the array elements.\n * @returns Returns the new duplicate free array.\n */\n\nexport function unique<TElem>(array: readonly TElem[], compareFn?: (a: TElem, b: TElem) => boolean): TElem[] {\n // Arrays optimized with native Set\n if (!compareFn)\n return [...new Set(array)];\n\n const uniqueArray: TElem[] = [];\n for (const value of array) {\n let isUnique = true;\n \n for (const uniqueValue of uniqueArray) {\n if (compareFn(value, uniqueValue)) {\n isUnique = false;\n break;\n }\n }\n \n if (isUnique)\n uniqueArray.push(value);\n }\n \n return uniqueArray;\n}\n","import type { CompareFunction } from '@helpers/ArrayTypeUtils.js';\nimport type { ArrayMinLength } from '@type/ArrayMinLength.js';\n\nimport { fastArrayFlat } from '@helpers/fastArrayFlat.js';\n\nimport { unique } from './unique.js';\n\n/**\n * Create an array with unique values that are present in all arrays. \n * The order of the values is based on the first array. \n * \n * Optionally, use a compare function for element comparison (default is `===`).\n * @example\n * intersection([2, 1], [2, 3], [6, 2])\n * // => [2]\n *\n * // ---- Custom compare function ----\n * const compareFn = (a, b) => Math.floor(a) === Math.floor(b);\n * \n * intersection([1.2, 1.1], [1.3, 2.4], compareFn)\n * // => [1.2]\n *\n * // ---- Only compare by id ----\n * const arr1 = [{ id: 1, name: 'Yeet' }, { id: 3, name: 'John' }];\n * const arr2 = [{ id: 3, name: 'Carl' }, { id: 4, name: 'Max' }];\n *\n * intersection(arr1, arr2, (a, b) => a.id === b.id)\n * // => [{ id: 3, name: 'John' }]\n * @param arraysOrCompareFn Two or more arrays with an optional compare function at the end.\n * @template TElem The type of the array elements.\n * @template TArrays The type of the arrays provided.\n * @returns Returns the new array of intersecting values.\n */\n\nexport function intersection<TElem>(...arraysOrCompareFn: ArrayMinLength<TElem[], 2>): TElem[];\nexport function intersection<TArrays extends ArrayMinLength<unknown[], 2>>(...arraysOrCompareFn: [...TArrays, CompareFunction<TArrays>]): TArrays[0];\nexport function intersection<TArrays extends ArrayMinLength<unknown[], 2>, TElem>(...arraysOrCompareFn: ArrayMinLength<TElem[], 2> | [...TArrays, CompareFunction<TArrays>]): TArrays[0] {\n const compareFnProvided = typeof arraysOrCompareFn.at(-1) === 'function';\n const compareFunction = compareFnProvided && arraysOrCompareFn.pop() as CompareFunction<TArrays>;\n\n const arrays = arraysOrCompareFn as TArrays;\n const firstArray = unique(arrays.shift()!);\n const combinedRestArray = fastArrayFlat(arrays);\n\n if (!compareFunction) {\n const restSet = new Set(combinedRestArray);\n return firstArray.filter(element => restSet.has(element));\n }\n \n const intersection: TArrays[0] = [];\n\n for (const element of firstArray) {\n if (combinedRestArray.some(item => compareFunction(element, item))) {\n intersection.push(element);\n }\n }\n\n return intersection;\n}\n","/**\n * Generates an iterable sequence of numbers starting from `start`, up to and including `end`,\n * with a given `step` between each number.\n *\n * @example\n * for (const num of range(1, 5)) {\n * console.log(num);\n * }\n * // => 1 2 3 4 5\n * \n * // Generate an array of even numbers between 0 and 10:\n * const arr = [...range(0, 10, 2)];\n * // => [0, 2, 4, 6, 8, 10]\n * \n * @param start The starting number of the sequence.\n * @param end The end number of the sequence.\n * @param step The step between each number in the sequence. Defaults to 1.\n *\n * @returns An iterable sequence of numbers between `start` and `end`, inclusive, with increments of `step`.\n */\nexport function* range(start: number, end: number, step = 1): Generator<number> {\n if (start > end)\n throw new Error('The start of the range must be less than or equal to the end.');\n\n if (step <= 0)\n throw new Error('The step must be greater than 0.');\n \n for (let i = start; i <= end; i += step) {\n yield i;\n }\n}","/**\n * Creates a new array of shuffled values, using the Fisher-Yates-Durstenfeld Shuffle algorithm.\n *\n * @example\n * shuffle([1, 2, 3, 4])\n * // => [4, 1, 3, 2]\n * @param array The array or object to shuffle.\n * @template TElem The type of the array elements.\n * @returns Returns a new shuffled array.\n */\n\nexport function shuffle<TElem>(array: readonly TElem[]): TElem[] {\n const shuffledArray = [...array];\n \n for (let index = shuffledArray.length - 1; index > 0; index--) {\n const randomIndex = Math.floor(Math.random() * (index + 1));\n [shuffledArray[index], shuffledArray[randomIndex]] = [shuffledArray[randomIndex], shuffledArray[index]];\n }\n \n return shuffledArray;\n}","\n/**\n * Creates a new sorted array in ascending or descending order based on one or multiple sorting criteria.\n * \n * @example\n * sort([1, 2, 3, 4], { order: 'desc' })\n * // => [4, 3, 2, 1]\n * \n * // --- Sorting by multiple properties ---\n * const array = [{ a: 2, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 1 }];\n * \n * sort(array,\n * { order: 'asc', by: item => item.a },\n * { order: 'desc', by: item => item.b }\n * )\n * // => [{ a: 1, b: 2 }, { a: 1, b: 1 }, { a: 2, b: 1 }]\n * @param array The array to sort.\n * @param orders The sorting criteria, one or multiple objects with properties order (either 'asc' or 'desc') and by (iteratee function to sort based on a specific property).\n * @param orders.order - The order to sort in, either 'asc' or 'desc'.\n * @param orders.by - The iteratee function to sort based on a specific property.\n * @template TElem The type of the array elements.\n * @returns Returns a new sorted array.\n*/\nexport function sort<TElem>(array: readonly TElem[], ...orders: { order?: 'asc' | 'desc', by?: (item: TElem) => number | bigint | Date | string }[]): TElem[] {\n return [...array].sort((a, b) => {\n for (const { order, by } of orders) {\n const aValue = by ? by(a) : a;\n const bValue = by ? by(b) : b;\n if (aValue < bValue) {\n return order === 'desc' ? 1 : -1; \n }\n if (aValue > bValue) {\n return order === 'desc' ? -1 : 1;\n }\n }\n return 0;\n });\n}","/**\n * Creates a slice of `array` with elements taken from the end. \n * Elements are taken until `predicate` returns falsey.\n * \n * @example\n * const users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': true }\n * ]\n *\n * takeRightWhile(users, user => user.active)\n * // => objects for ['fred', 'pebbles']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function takeRightWhile<TElem>(array: readonly TElem[], predicate: (elem: TElem) => boolean): TElem[] {\n const result: TElem[] = [];\n\n for (let i = array.length - 1; i >= 0; i--) {\n if (predicate(array[i])) {\n result.unshift(array[i]);\n } else {\n break;\n }\n }\n\n return result;\n}\n","/**\n * Creates a slice of `array` with elements taken from the beginning. \n * Elements are taken until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': false }\n * ]\n *\n * takeWhile(users, user => user.active)\n * // => objects for ['barney', 'fred']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function takeWhile<TElem>(array: readonly TElem[], predicate: (elem: TElem) => boolean): TElem[] {\n const result: TElem[] = [];\n\n for (const element of array) {\n if (predicate(element)) {\n result.push(element);\n } else {\n break;\n }\n }\n\n return result;\n}\n","import type { Jsonifiable } from '@type/Jsonifiable.js';\n\ntype SupportedAlgorithms = 'SHA-256' | 'SHA-384' | 'SHA-512';\n\nlet textEncoder: TextEncoder | undefined;\n\n/**\n * Generates a hash from the given data using the specified algorithm.\n *\n * It uses the Web Crypto API to generate the hash.\n * \n * *Note: If you need a secure hash use a specialized library like [crypto-js](https://www.npmjs.com/package/crypto-js) instead.*\n * \n * @example\n * // Hash a string using the default algorithm (SHA-256)\n * await hash('hello world'); \n * // => \"b94d27b9934d3e08a52e52d7da7dabfac484efe37a53...\"\n *\n * // Hash an object using the SHA-512 algorithm\n * await hash({ foo: 'bar', baz: 123 }, 'SHA-512');\n * // => \"d8f3c752c6820e580977099368083f4266b569660558...\"\n * \n * @param data The data to hash, either as a string or a JSON-serializable object.\n * @param algorithm The hashing algorithm to use. Defaults to 'SHA-256'.\n * @returns A Promise that resolves to the hexadecimal representation of the hash.\n *\n * @throws {DOMException} If the specified algorithm is not supported by the Web Crypto API.\n */\n\nexport async function hash(data: Jsonifiable, algorithm: SupportedAlgorithms = 'SHA-256'): Promise<string> {\n textEncoder ??= new TextEncoder();\n\n const dataBuffer = typeof data === 'string'\n ? textEncoder.encode(data) \n : textEncoder.encode(JSON.stringify(data));\n \n const hashBuffer = await crypto.subtle.digest(algorithm, dataBuffer);\n const hashArray = [...new Uint8Array(hashBuffer)];\n const hexValues = hashArray.map(b => b.toString(16).padStart(2, '0'));\n return hexValues.join('');\n}\n","\n/**\n * Generates a random integer between two given numbers, including those numbers.\n * \n * It uses `crypto.getRandomValues` to generate the random number.\n * @example\n * randomInt(1, 10) \n * // => 5\n * \n * @param min The smallest integer that can be generated.\n * @param max The largest integer that can be generated.\n * \n * @returns A random integer between `min` and `max`, including `min` and `max`.\n */\n\nexport function randomInt(min: number, max: number): number {\n // Taken from https://stackoverflow.com/a/41452318\n if (!Number.isInteger(min) || !Number.isInteger(max))\n throw new TypeError('min and max must be integers');\n\n if (min >= max) \n throw new Error('max must be greater than min');\n\n const range = max - min + 1;\n const randomBytes = Math.ceil(Math.log2(range) / 8);\n const maxRandNumber = Math.pow(256, randomBytes);\n const randomBuffer = new Uint8Array(randomBytes);\n\n let randomValue: number;\n do {\n crypto.getRandomValues(randomBuffer);\n randomValue = 0;\n for (let index = 0; index < randomBytes; index++) {\n // eslint-disable-next-line no-bitwise\n randomValue = (randomValue << 8) + randomBuffer[index];\n }\n // rerun if randomValue is bigger than range\n } while (randomValue >= maxRandNumber - (maxRandNumber % range));\n\n return min + (randomValue % range);\n}\n","import { randomInt } from './randomInt.js';\n\n/**\n * Gets a random element an array. A single element is returned by default. \n * Specify the `multi` parameter to get an array of multiple random elements.\n *\n * If the array is empty, `undefined` is returned. \n * If `multi` is defined it returns an empty array.\n * \n * It uses `crypto.getRandomValues` to get the random element.\n * @example\n * randomElem([1, 2, 3, 4])\n * // => 2\n *\n * randomElem([1, 2, 3, 4], 2)\n * // => [3, 1]\n * @param array The array to sample.\n * @returns Returns the random element.\n */\n\nexport function randomElem<TArr>(array: TArr[]): TArr | undefined;\nexport function randomElem<TArr>(array: TArr[], multi: number): TArr[];\nexport function randomElem<TArr>(array: TArr[], multi?: number): TArr | undefined | TArr[] {\n if (multi === undefined) {\n if (array.length === 0) return undefined;\n return getSingleElement(array);\n }\n\n if (multi && array.length === 0) return [];\n\n // Multiple samples\n const result = new Array<TArr>(multi);\n for (let i = 0; i < multi; i++) {\n result[i] = getSingleElement(array);\n }\n return result;\n}\n\nfunction getSingleElement<TArr>(array: TArr[]): TArr {\n const randomIndex = randomInt(0, array.length - 1);\n return array[randomIndex];\n}","/* eslint-disable no-bitwise */\nconst shiftLeft20Bits = 2 ** 20;\nconst shiftRight52Bits = 2 ** -52;\n\n/**\n * Generates a random float between two given numbers, including those numbers.\n * \n * It uses `crypto.getRandomValues` to generate the random number.\n * @example\n * randomFloat(1, 10) \n * // => 1.123456789\n * \n * @param min The smallest float that can be generated.\n * @param max The largest float that can be generated.\n * \n * @returns A random float between `min` and `max`, including `min` and `max`.\n */\n\nexport function randomFloat(min: number, max: number): number {\n if (min >= max) {\n throw new Error('max must be greater than min');\n }\n const range = max - min;\n const randomBuffer = new Uint32Array(2);\n crypto.getRandomValues(randomBuffer);\n\n // keep all 32 bits of the the first, top 20 of the second for 52 random bits\n const mantissa = (randomBuffer[0] * shiftLeft20Bits) + (randomBuffer[1] >>> 12);\n\n // shift all 52 bits to the right of the decimal point\n const randomFloat = mantissa * shiftRight52Bits;\n return min + (randomFloat * range);\n}","import { randomInt } from './randomInt.js';\n\nconst DEFAULT_CHARSET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n\n/**\n * Generates a random string of the specified length.\n * The default charset is alphanumeric characters.\n * \n * It uses `crypto.getRandomValues` to generate the random string.\n * \n * @example\n * randomString(8);\n * // => \"JWw1p6rD\"\n *\n * randomString(16, 'abc');\n * // => \"cbaacbabcabccabc\"\n * @param length The length of the string to generate.\n * @param charSet The set of characters to use when generating the string. Defaults to alphanumeric characters.\n * @returns A random string of the specified length.\n */\n\nexport function randomString(length: number, charSet = DEFAULT_CHARSET): string {\n if (charSet.length <= 0) return '';\n\n let result = '';\n for (let index = 0; index < length; index++) {\n const randomIndex = randomInt(0, charSet.length - 1);\n result += charSet[randomIndex];\n }\n\n return result;\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\ntype Tail<T extends unknown[]> = T extends [infer _Head, ...infer Tail] ? Tail : never;\n\n/**\n * Transforms a function that takes a function as first argument into a decorator function.\n * \n * @example\n * ```typescript\n * function log(func: Function, message: string) {\n * return function (...args: unknown[]) {\n * console.log(message);\n * return func(...args);\n * };\n * }\n * \n * const logger = toDecorator(log);\n * \n * class TestClass {\n * @logger(\"Hello world!\")\n * testMethod() {\n * return 1; \n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(); \n * // => Log \"Hello World\" and return 1\n * ```\n * @param func The function to transform.\n * @returns A decorator function that can be used to decorate a method.\n */\n\nexport function toDecorator<TFunc extends GenericFunction<TFunc>>(func: TFunc) {\n return function (...args: Tail<Parameters<TFunc>>) {\n return function (target: unknown, key: string, descriptor: PropertyDescriptor) {\n const creatorArgs = [descriptor.value, ...args] as Parameters<TFunc>;\n descriptor.value = func(...creatorArgs);\n };\n };\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a debounced version of a function. Only calling it after a specified amount of time has passed without any new calls.\n * \n * **Methods:** \n * - `cancel` will cancel the next invocation of the debounced function. \n * - `flush` will immediately invoke the debounced function and cancel any pending invocations. \n * \n * This function can be used as a decorator with {@link decDebounce}.\n * \n * @example\n * const sayHello = (name: string) => console.log(`Hello, ${name}!`);\n * const debouncedSayHello = debounce(sayHello, 200);\n * \n * debouncedSayHello(\"John\");\n * debouncedSayHello(\"Jane\");\n * // => Only the second invocation of `debouncedSayHello` is executed, after a delay of 200ms.\n * @param func The function to debounce.\n * @param wait The number of milliseconds to wait before invoking `func`.\n * @returns A debounced version of `func` with `cancel` and `flush` methods.\n */\n\nexport function debounce<TFunc extends GenericFunction<TFunc>>(func: TFunc, wait: number): TFunc & {\n cancel: () => void;\n flush: () => void;\n} {\n let timeoutId: NodeJS.Timeout | undefined;\n const debounced = function (this: unknown, ...args: Parameters<TFunc>) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => func.apply(this, args), wait);\n };\n\n /** Cancels the next invocation of the debounced function. */\n debounced.cancel = function () {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n };\n\n /** Immediately invokes the debounced function and cancels any pending invocations. */\n debounced.flush = function (this: unknown, ...args: Parameters<TFunc>) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n func.apply(this, args);\n };\n\n return debounced as TFunc & { cancel: () => void; flush: () => void };\n}","import { toDecorator } from '@decorator/toDecorator.js';\nimport { debounce } from '@function/debounce.js';\n\n/**\n * Debouces the decorated function. Only calling it after a specified amount of time has passed without any new calls.\n * \n * Look at {@link debounce} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decDebounce(100)\n * testMethod(str: string) {\n * console.log(\"Debounced:\", str);\n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(\"Hello\");\n * instance.testMethod(\"World\");\n * // => Only the second invocation of `debouncedSayHello` is executed, after a delay of 1000ms.\n * ```\n * @param wait Milliseconds to wait before invoking the decorated function after the last invocation.\n */\n\nexport function decDebounce(wait: number) {\n return toDecorator(debounce)(wait);\n}\n","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a function that invokes the given function as long as it's called `<= n` times.\n * \n * Subsequent calls to the created function return the result of the last `func` invocation.\n *\n * This function can be used as a decorator with {@link decMaxCalls}.\n * @example\n * let count = 0;\n * const addCount = () => ++count;\n *\n * // Allow addCount to be invoked twice.\n * const limitAddCount = maxCalls(addCount, 2)\n *\n * limitAddCount() // => 1\n * limitAddCount() // => 2\n * limitAddCount() // => 2\n * // => `limitAddCount` is invoked twice and the result is cached.\n * @param n The number of calls before the cached result is returned.\n * @param func The function to restrict.\n * @returns Returns the new restricted function.\n */\n\nexport function maxCalls<TFunc extends GenericFunction<TFunc>>(func: TFunc, n: number): TFunc {\n let count = 0;\n let result: ReturnType<TFunc>;\n return function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> {\n if (count < n) {\n count += 1;\n result = func.apply(this, args);\n }\n return result;\n } as TFunc;\n}\n","import { toDecorator } from '@decorator/toDecorator.js';\nimport { maxCalls } from '@function/maxCalls.js';\n\n/**\n * Only invokes the decorated function as long as it's called `<= n` times. \n * Subsequent calls to the decorated function return the result of the last invocation.\n * \n * Look at {@link maxCalls} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * private count = 0;\n * @decMaxCalls(2)\n * testMethod() {\n * return ++this.count;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(); // => 1 \n * instance.testMethod(); // => 2\n * instance.testMethod(); // => 2\n * ```\n * @param n The number of calls before the cached result is returned.\n */\n\nexport function decMaxCalls(n: number) {\n return toDecorator(maxCalls)(n);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\nconst defaultResolver = (...args: unknown[]) => JSON.stringify(args);\n\n/**\n * Creates a function that memoizes the result of a given function.\n * \n * The cache key is determined by the `resolver` or by the arguments from the function call.\n *\n * **Options:**\n * - `resolver` A function that determines the cache key based on the arguments provided.\n * - `ttl` the time to live for the cache entries in milliseconds.\n * \n * **Properties:**\n * - `cache` The cache is an instance of `Map` and can be used to clear or inspect the cache. \n * It can be replaced by a custom cache that matches the `Map` interface.\n * \n * \n * This function can be used as a decorator with {@link decMemoize}.\n * \n * @example\n * ```typescript\n * function fibonacci(n: number) {\n * if (n <= 1) return n;\n * return fibonacci(n - 1) + fibonacci(n - 2);\n * }\n *\n * const memoizedFib = memoize(fibonacci, { ttl: 1000 })\n * \n * memoizedFib(40) // => 102334155\n * memoizedFib(40) // => 102334155 (cache hit)\n * setTimeout(() => memoizedFib(40), 1000) // => 102334155 (cache miss)\n * \n * // Cached values are exposed as the `cache` property.\n * memoizedFib.cache.get(\"40\") // => [value, timestamp]\n * memoizedFib.cache.set(\"40\", [1234, Date.now()])\n * memoizedFib.cache.clear()\n * \n * // This is the default way to create cache keys.\n * const defaultResolver = (...args: unknown[]) => JSON.stringify(args)\n * ```\n * @param func The function to have its output memoized.\n * @param options The options object with optional `resolver` and `ttl` parameters.\n * @param options.resolver - A function that determines the cache key for storing the result based on the arguments provided.\n * @param options.ttl - The time to live for the cache in milliseconds.\n * @template TFunc The type of the function to memoize.\n * @template Cache The type of the cache storage.\n * @returns Returns the new memoized function.\n */\n\nexport function memoize<TFunc extends GenericFunction<TFunc>, Cache extends Map<string, [ReturnType<TFunc>, number]>>(\n func: TFunc, options: { resolver?: (...args: Parameters<TFunc>) => string, ttl?: number; } = {}\n): TFunc & { cache: Cache } {\n const resolver = options.resolver ?? defaultResolver;\n const ttl = options.ttl;\n const cache = new Map() as Cache;\n\n const memoizedFunc = function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> {\n const key = resolver(...args);\n if (cache.has(key)) {\n const [cacheResult, cacheTime] = cache.get(key)!;\n if (ttl === undefined || (Date.now() - cacheTime < ttl)) {\n return cacheResult;\n }\n }\n const result = func.apply(this, args);\n cache.set(key, [result, Date.now()]);\n return result;\n };\n\n memoizedFunc.cache = cache;\n return memoizedFunc as TFunc & { cache: Cache };\n} ","import { toDecorator } from '@decorator/toDecorator.js';\nimport { memoize } from '@function/memoize.js';\n\n/**\n * Memoizes the decorated function. \n * The cache key is either determined by the provided resolver or by the arguments used in the memoized function.\n * \n * **Options:**\n * - `resolver` A function that determines the cache key for storing the result based on the arguments provided.\n * - `ttl` sets the time to live for the cache in milliseconds. After `ttl` milliseconds, the next call to the memoized function will result in a cache miss.\n * \n * Look at {@link memoize} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decMemoize({ ttl: 1000 })\n * testMethod(a: number, b: number) {\n * return a + b;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(1, 2); // => 3\n * instance.testMethod(1, 2); // => 3 (cached)\n * \n * // After 1 second:\n * instance.testMethod(1, 2); // => 3 (cache miss)\n * ```\n * @param options The options object.\n * @param options.resolver - A function that determines the cache key for storing the result based on the arguments provided.\n * @param options.ttl - The time to live for the cache in milliseconds.\n */\n\nexport function decMemoize(options: Parameters<typeof memoize>[1] = {}) {\n return toDecorator(memoize)(options);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a function that invokes the given function once it's called more than `n` times. \n * Returns undefined until the minimum call count is reached.\n * \n * This function can be used as a decorator with {@link decMinCalls}.\n * @example\n * const caution = () => console.log(\"Caution!\");\n * const limitedCaution = minCalls(caution, 2);\n *\n * limitedCaution()\n * limitedCaution()\n * limitedCaution()\n * // => `caution` is invoked on the third call.\n * @param n The number of calls before the given function is invoked.\n * @param func The function to restrict.\n * @returns Returns the new restricted function.\n */\n\nexport function minCalls<TFunc extends GenericFunction<TFunc>>(func: TFunc, n: number) {\n let count = 1;\n return function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> | undefined {\n if (count > n) {\n return func.apply(this, args);\n }\n count += 1;\n };\n}","import { toDecorator } from '@decorator/toDecorator.js';\nimport { minCalls } from '@function/minCalls.js';\n\n/** \n * Only invokes the decorated function after it's called more than `n` times.\n * \n * Look at {@link minCalls} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * @example\n * ```typescript\n * class TestClass {\n * @decMinCalls(2)\n * testMethod() {\n * return 1;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(); // => undefined\n * instance.testMethod(); // => undefined\n * instance.testMethod(); // => 1\n * ```\n * @param n The number of calls before the decorated function is invoked.\n */\n\nexport function decMinCalls(n: number) {\n return toDecorator(minCalls)(n);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Generates a function that invokes the given function at most once per every `wait` milliseconds.\n * \n * This function can be used as a decorator with {@link decThrottle}.\n * @example\n * const throttled = throttle(() => console.log(\"Throttled!\"), 1000);\n * \n * throttled();\n * throttled();\n * // => \"Throttled!\" is logged once per second.\n * @param func The function to throttle.\n * @param wait The number of milliseconds to throttle invocations to.\n * @returns Returns the new throttled function.\n */\n\n\nexport function throttle<TFunc extends GenericFunction<TFunc>>(func: TFunc, wait: number): TFunc {\n let inThrottle = false;\n return function (this: unknown, ...args: Parameters<TFunc>) {\n if (!inThrottle) {\n func.apply(this, args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), wait);\n }\n } as TFunc;\n}\n \n","import { toDecorator } from '@decorator/toDecorator.js';\nimport { throttle } from '@function/throttle.js';\n\n/**\n * The decorated function is invoked at most once per every `wait` milliseconds.\n * \n * Look at {@link throttle} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decThrottle(1000)\n * testMethod() {\n * console.log(\"Throttled!\");\n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(); // => \"Throttled!\" is logged once per second.\n * instance.testMethod(); // nothing happens\n * ```\n * @param wait The number of milliseconds to wait between invocations.\n */\n\nexport function decThrottle(wait: number) {\n return toDecorator(throttle)(wait);\n}","/**\n * Invokes a function `n` times, returning an array of the results of\n * each invocation.\n * \n * @example\n * times(index => console.log(\"Run\", index), 3)\n * // => \"Run 0\" | \"Run 1\" | \"Run 2\"\n * times(Math.random, 3)\n * // => [0.123, 0.456, 0.789]\n * times(() => 0, 4)\n * // => [0, 0, 0, 0]\n * @param n The number of times to invoke `func`.\n * @param func The function invoked per iteration.\n * @returns Returns an array of results.\n */\n\nexport function times<TInput>(func: (index: number) => TInput, n: number): TInput[] {\n const result: TInput[] = [];\n for (let i = 0; i < n; i++) {\n result.push(func(i));\n }\n return result;\n}","/**\n * Calculates the sum of an array of numbers.\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * sum([1, 2, 3, 4, 5]) // => 15\n * \n * @param numbers The input array of numbers\n * @returns The sum of the input array \n */\n\nexport function sum(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n return numbers.reduce((total, current) => total + current, 0);\n}","import { sum } from '@number/sum.js';\n\n/**\n * Calculates the average of an array of numbers\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * average([1, 2, 3, 4, 5]) // => 3\n * \n * @param numbers The input array of numbers\n * @returns The average of the input array, or NaN if the input array is empty\n */\n\nexport function average(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n return sum(numbers) / numbers.length;\n}","/**\n * Calculates the median of an array of numbers\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * median([1, 2, 3, 4, 5]) // => 3\n * median([1, 2, 3, 4, 5, 6]) // => 3.5\n * \n * @param numbers The input array of numbers\n * @returns The median of the input array\n */\n\nexport function median(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n const sortedArray = [...numbers].sort((a, b) => a - b);\n const mid = Math.floor(sortedArray.length / 2);\n return sortedArray.length % 2 === 0 ? ((sortedArray[mid - 1] + sortedArray[mid]) / 2) : sortedArray[mid];\n}","/**\n * Rounds a number to the given precision.\n *\n * @example\n * round(1.23456, 2); // => 1.23\n * round(1.235, 1); // => 1.2\n * round(1234.56); // => 1234.56\n * \n * @param number The number to be rounded.\n * @param precision The number of decimal places to round to. Defaults to 2.\n * @returns The rounded number.\n */\n\nexport function round(number: number, precision = 2): number {\n const factor = Math.pow(10, precision);\n return Math.round((number + Number.EPSILON) * factor) / factor;\n}","import type { PlainObject } from '@type/PlainObject.js';\n\n/**\n * Checks if the value is a plain object.\n * \n * @example\n * isPlainObject({}) // => true\n * isPlainObject({ a: 1 }) // => true\n * isPlainObject(null) // => false\n * isPlainObject('1') // => false\n * isPlainObject([]) // => false\n * isPlainObject(new Function()) // => false\n * isPlainObject(new Date()) // => false\n * @param value The value to check\n * @returns Boolean indicating if the value is a plain object\n */\n\nexport function isPlainObject(value: unknown): value is PlainObject {\n return value?.constructor === Object;\n}","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\n/**\n * Flattens an object into a single level object.\n * \n * @example\n * const obj = { a: { b: 2, c: [{ d: 3 }, { d: 4 }] } };\n * flatKeys(obj);\n * // => { 'a.b': 2, 'a.c[0].d': 3, 'a.c[1].d': 4 }\n * \n * @param obj The object to flatten.\n * @template TObj The type of the object to flatten.\n * @returns A new object with flattened keys.\n */\n\nexport function flatKeys<TObj extends PlainObject>(obj: TObj): Record<string, unknown> {\n const flatObject: Record<string, unknown> = {};\n \n for (const [key, value] of Object.entries(obj)) {\n addToResult(key, value, flatObject);\n }\n \n return flatObject;\n}\n\nfunction addToResult(prefix: string, value: unknown, flatObject: Record<string, unknown>) {\n if (isPlainObject(value)) {\n const flatObj = flatKeys(value);\n for (const [flatKey, flatValue] of Object.entries(flatObj)) {\n flatObject[`${prefix}.${flatKey}`] = flatValue;\n }\n } else if (Array.isArray(value)) {\n for (const [index, element] of value.entries()) {\n addToResult(`${prefix}[${index}]`, element, flatObject);\n }\n\n } else {\n flatObject[prefix] = value;\n }\n}\n","import type { ArrayMinLength } from '@type/ArrayMinLength.js';\nimport type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\n/**\n * This function combines two or more objects into a single new object. Arrays and other types are overwritten.\n * \n * @example\n * // ---- Nested objects are merged ----\n * merge({ a: 1 }, { b: 2 }, { c: 3, d: { e: 4 } }) \n * // => { a: 1, b: 2, c: 3, d: { e: 4 } }\n *\n * // ---- Other types are overwritten ----\n * merge({ a: [1, 2] }, { a: [3, 4] })\n * // => { a: [3, 4] }\n * \n * merge({ a: 1 }, { a: \"Yes\" })\n * // => { a: \"Yes\" }\n * @param target The target object\n * @param sources The source objects\n * @template TTarget The type of the target object\n * @template TSources The type of the source objects\n * @returns A new merged object\n */\n\nexport function merge<TTarget extends PlainObject, TSources extends ArrayMinLength<PlainObject, 1>>(target: TTarget, ...sources: TSources): MergeDeepObjects<[TTarget, ...TSources]> {\n const targetCopy = { ...target };\n for (const source of sources) {\n for (const [key, value] of Object.entries(source)) {\n (targetCopy as PlainObject)[key] = isPlainObject(value) && isPlainObject(targetCopy[key]) \n ? merge(targetCopy[key] as PlainObject, value) \n : value;\n }\n }\n return targetCopy as MergeDeepObjects<[TTarget, ...TSources]>; \n}\n\ntype OptionalPropertyNames<T> =\n { [K in keyof T]-?: (PlainObject extends { [P in K]: T[K] } ? K : never) }[keyof T];\n\ntype SpreadProperties<L, R, K extends keyof L & keyof R> =\n { [P in K]: L[P] | Exclude<R[P], undefined> };\n\ntype Id<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;\n\ntype SpreadTwo<L, R> = Id<\n& Pick<L, Exclude<keyof L, keyof R>>\n& Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>>\n& Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>>\n& SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>\n>;\n\ntype MergeDeepObjects<A extends readonly [...unknown[]]> = A extends [infer L, ...infer R] ?\n SpreadTwo<L, MergeDeepObjects<R>> : unknown;\n","import type { PlainObject } from '@type/PlainObject.js';\n\n/**\n * Creates an object composed of the picked `object` properties.\n *\n * @example\n * const object = { 'a': 1, 'b': '2', 'c': 3 }\n *\n * pick(object, ['a', 'c'])\n * // => { 'a': 1, 'c': 3 }\n * @param object The source object.\n * @param keysToPick The property paths to pick.\n * @template TObj The type of the object.\n * @returns Returns the new object.\n */\n\nexport function pick<TObj extends PlainObject, Key extends keyof TObj>(object: TObj, keysToPick: Key[]): Pick<TObj, Key> {\n const result = {} as Pick<TObj, Key>;\n for (const key of keysToPick) {\n result[key] = object[key];\n }\n return result;\n}\n","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { pick } from './pick.js';\n\n/**\n * Omit specified keys from an object\n *\n * @example\n * const obj = {a: 1, b: 2, c: 3};\n * omit(obj, ['a', 'b']);\n * // => {c: 3}\n *\n * @param object The object to filter\n * @param keysToOmit The keys to exclude from the returned object\n * @template TObj The type of the object\n * @returns - An object without the specified keys\n */\n\nexport function omit<TObj extends PlainObject, Key extends keyof TObj>(object: TObj, keysToOmit: Key[]): Omit<TObj, Key> {\n const keys = Object.keys(object);\n const filteredKeys = keys.filter(key => !keysToOmit.includes(key as Key)) as Exclude<keyof TObj, Key>[];\n\n return pick(object, filteredKeys);\n}","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\nconst validPathRegex = /^(?:[^.[\\]]+(?:\\[\\d+])*(?:\\.|\\[\\d+]))+(?:[^.[\\]]+(?:\\[\\d+])*)+$/;\nconst pathSplitRegex = /\\.|(?=\\[)/g;\nconst matchBracketsRegex = /[[\\]]/g;\n\n/**\n * Sets the value at path of object. If a portion of path doesn’t exist, it’s created.\n * \n * @example\n * const obj = { a: { b: 2 } };\n * set(obj, 'a.c', 1);\n * // => { a: { b: 2, c: 1 } }\n * \n * // `[number]` can be used to access array elements\n * set(obj, 'a.c[0]', 'hello');\n * // => { a: { b: 2, c: ['hello'] } }\n * \n * // numbers with dots are treated as keys\n * set(obj, 'a.c.0.d', 'world');\n * // => { a: { b: 2, c: { 0: { d: 'world' } } }\n * \n * // supports numbers in keys\n * set(obj, 'a.e0.a', 1);\n * // => { a: { e0: { a: 1 } } }\n * \n * @param obj The object to modify.\n * @param path The path of the property to set.\n * @param value The value to set.\n * @template TObj The type of the object.\n * @returns The modified object.\n */\n\nexport function set(obj: PlainObject, path: string, value: unknown): PlainObject {\n if (!validPathRegex.test(path))\n throw new Error('Invalid path, look at the examples for the correct format.');\n\n const pathParts = path.split(pathSplitRegex);\n let currentObj: PlainObject = obj;\n for (let index = 0; index < pathParts.length; index++) {\n const key = pathParts[index].replace(matchBracketsRegex, '');\n\n if (index === pathParts.length - 1) {\n currentObj[key] = value;\n break;\n }\n\n const nextElemIn = pathParts[index + 1].startsWith('[') ? 'array' : 'object';\n if (currentObj[key] === undefined) {\n currentObj[key] = nextElemIn === 'array' ? [] : {};\n } else if (nextElemIn === 'array' && !Array.isArray(currentObj[key])) {\n currentObj[key] = [];\n } else if (nextElemIn === 'object' && !isPlainObject(currentObj[key])) {\n currentObj[key] = {};\n }\n currentObj = currentObj[key] as PlainObject;\n }\n\n return obj;\n}","/**\n * A class for managing a queue of async functions that runs a set number concurrently. \n * If for example you have 10 async functions and you want to run 3 at a time, you can use this class.\n * \n * If the queue is paused, the queue will not run any more async functions until it is resumed.\n * \n * **Methods:**\n * - `add` - adds a async function or array of functions to the queue. Returns a promise that resolves when the added function(s) finish.\n * - `clear` - clears the queue.\n * - `pause` - pauses the queue.\n * - `resume` - resumes the queue. \n * - `getQueue` - returns the current queue.\n * - `isPaused` - returns whether the queue is paused.\n * \n * @example\n * // Create a queue that can run 3 tasks concurrently\n * const queue = new Queue(3);\n * \n * queue.add(() => fetch('https://example.com'));\n * \n * queue.add(async () => {\n * const response = await fetch('https://example.com');\n * return response.json();\n * });\n * \n * // Add an array of tasks to the queue and wait for them to resolve\n * await queue.add([\n * () => fetch('https://apple.com'),\n * () => fetch('https://microsoft.com')\n * ]);\n * // => [Response, Response]\n */\n\nexport class Queue {\n private running = 0;\n private maxConcurrent: number;\n private paused = false;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private queue: { asyncFn: () => Promise<any>, resolve: (value: any) => void, reject: (reason?: any) => void }[] = [];\n\n /**\n * @constructor\n * @param maxConcurrent The maximum number of async functions to run concurrently.\n */\n constructor(maxConcurrent: number) {\n this.maxConcurrent = maxConcurrent;\n }\n\n /**\n * Add aync functions or an array of async functions to the queue.\n * \n * @param asyncFn The aync function(s) to add to the queue.\n * @returns A promise that resolves when the added function(s) finishes.\n */\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn): Promise<TProm>;\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn[]): Promise<TProm[]>;\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn | TAsyncFn[]): Promise<TProm> | Promise<TProm[]> {\n if (Array.isArray(asyncFn)) {\n const promises = asyncFn.map((fn) => this.buildWaitingPromise(fn));\n return Promise.all(promises);\n } else {\n return this.buildWaitingPromise(asyncFn);\n } \n }\n\n private buildWaitingPromise<TProm>(asyncFn: () => Promise<TProm>): Promise<TProm> {\n return new Promise((resolve, reject) => {\n this.queue.push({ asyncFn, resolve, reject });\n this.run();\n });\n } \n\n private run() {\n while (this.queue.length > 0 && this.running < this.maxConcurrent && !this.paused) {\n this.running++;\n const queueElement = this.queue.shift()!;\n void queueElement.asyncFn()\n .then((result) => {\n queueElement.resolve(result);\n }).catch((error) => {\n queueElement.reject(error);\n }).finally(() => {\n this.running--;\n this.run();\n });\n }\n }\n\n /** Removes all the tasks from the queue */\n clear() {\n for (const queueElement of this.queue) {\n queueElement.reject(new Error('Queue cleared'));\n }\n this.queue = [];\n }\n\n /** Pauses the execution of the queue */\n pause() {\n this.paused = true;\n }\n\n /** Resumes the execution of the tasks in the queue */\n resume() {\n this.paused = false;\n this.run();\n }\n\n /** Return the tasks added to the queue */\n getQueue() {\n return this.queue.map((queueElement) => queueElement.asyncFn);\n }\n\n /** Returns whether the queue is paused */\n isPaused() {\n return this.paused;\n }\n\n}\n","/**\n * Similar to [Promise.race](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race?retiredLocale=de) \n * but allows to specify how many promises to wait for.\n *\n * @example\n * const prom1 = Promise.resolve(1);\n * const prom2 = new Promise(resolve => setTimeout(resolve, 100, 2));\n * const prom3 = Promise.resolve(3);\n * \n * const firstTwo = await races(2, prom1, prom2, prom3);\n * // => [1, 3]\n * \n * @template TRes The type of the result of the promises.\n * @param waitFor The number of promises to wait for.\n * @param promises The promises to wait for.\n * @returns A promise that resolves an array of the results of the first n promises.\n */\n\nexport function races<TRes>(waitFor: number, ...promises: Promise<TRes>[]): Promise<TRes[]> {\n return new Promise((resolve, reject) => {\n if (promises.length < waitFor)\n waitFor = promises.length;\n\n const results: TRes[] = [];\n let resolved = 0;\n for (const promise of promises) {\n promise.then((value) => {\n results.push(value);\n resolved++;\n if (resolved >= waitFor) {\n resolve(results);\n }\n }).catch((error) => {\n reject(error);\n });\n }\n });\n}","/**\n * Sleeps for the given amount of time.\n *\n * @example\n * await sleep(1000);\n * // => Waits for 1 second.\n * @param ms Amount of time to sleep in milliseconds.\n * @returns A promise that resolves after the given amount of time.\n */\nexport function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}","/* eslint-disable no-await-in-loop */\nimport { sleep } from '@promise/sleep.js';\n\n/**\n * Retry a function until it succeeds or the maximum number of retries is reached.\n * \n * Default maxRetries: `5`. \n * Default backoff: `2^retries * 100ms` (100, 200, 400, 800, 1600, 3200, ...)\n *\n * @example\n * await retry(() => fetch('https://example.com'));\n * \n * // ---- Advanced example ----\n * const fetchSite = async () => {\n * const response = await fetch('https://example.com');\n * if(!response.ok)\n * throw new Error('Failed to fetch');\n * }\n * \n * const logger = (error: unknown, retry?: number) => console.log(\"Retrying\", retry, error);\n * \n * await retry(fetchSite, { maxRetries: 3, backoff: retries => retries * 1000, onRetry: logger });\n * // => Will retry 3 times with a 1 second delay between each retry.\n * // => Will log the error and retry number.\n * \n * @param func The function to retry.\n * @param options The options for the retry.\n * @param options.maxRetries The maximum number of retries. Defaults to `5`.\n * @param options.backoff The backoff function to use. Defaults to `2^retries * 100`.\n * @param options.onRetry The function to call when a retry is attempted. It will be called with the error and the attempt number.\n * @template TRes The type of the result of the function.\n * @returns A promise that resolves when the function succeeds.\n */\n\nexport async function retry<TRes>(\n func: () => Promise<TRes>, \n options?: { \n maxRetries?: number,\n backoff?: ((retries: number) => number),\n onRetry?: (error?: unknown, attempted?: number) => void\n }\n): Promise<TRes> {\n const backOffFn = options?.backoff ?? (retries => (2 ** retries) * 100);\n const maxRetries = options?.maxRetries ?? 5;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n const onRetry = options?.onRetry ?? (() => {});\n let retries = 0;\n let lastError: unknown;\n\n while (retries <= maxRetries) {\n try {\n if (retries > 0)\n onRetry(lastError, retries);\n return await func();\n } catch (error) {\n lastError = error;\n retries++;\n if (retries > maxRetries) {\n throw error;\n }\n await sleep(backOffFn(retries));\n }\n /* c8 ignore next 2 */\n }\n throw new Error('Retry terminated without success, this should never happen');\n}","/**\n * Returns a new promise that will reject with an error after a specified timeout. \n *\n * @example\n * try {\n * await timeout(fetch('https://example.com'), 1000);\n * } catch (error) {\n * console.log(error.message);\n * // => 'Promise timed out after 1000ms'\n * }\n * @template TRes - The type of the resolved value.\n * @param promise The promise to wrap.\n * @param timeout The timeout in milliseconds.\n * \n * @returns A new promise that will reject with an error after the specified timeout.\n */\nexport function timeout<TRes>(promise: Promise<TRes>, timeout: number): Promise<TRes> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error(`Promise timed out after ${timeout}ms`));\n }, timeout);\n \n promise.then(\n (result) => {\n clearTimeout(timeoutId);\n resolve(result);\n },\n (error) => {\n clearTimeout(timeoutId);\n reject(error);\n }\n );\n });\n}","/**\n * Attempts to execute a promise and returns an array with the result or error.\n * \n * This is useful for handling errors in async functions without try/catch blocks.\n * \n * @example\n * ```typescript\n * const [data, error] = await tryCatch(fetch('https://example.com/api'));\n * if (error)\n * console.error(`Error: ${error.message}`);\n * ```\n * @param promise A Promise to be executed.\n * @returns A Promise that resolves to an array containing the result or error. \n * If the Promise executes successfully, the array contains the result and a null error. \n * If the Promise throws an error, the array contains undefined for the result and the error object.\n *\n * @template TRes The type of the result.\n */\n\nexport async function tryCatch<TRes>(promise: Promise<TRes>): Promise<[TRes, undefined] | [undefined, Error]> {\n try {\n const data = await promise;\n return [data, undefined];\n } catch (error) {\n if (error instanceof Error)\n return [undefined, error];\n\n throw error;\n }\n}","// Split non-alphanumeric characters with spaces and deal with camel/PascalCase\nconst splitWordsRegex = new RegExp(\n '[^\\\\dA-Za-z]' + // match any character that is not a letter or a digit\n '|' + // or\n '(?<=[a-z])' + // lookbehind for a lowercase letter\n '(?=[A-Z])' + // lookahead for an uppercase letter\n '|' + // or\n '(?<=[A-Z])' + // lookbehind for an uppercase letter\n '(?=[A-Z][a-z])' // lookahead for an uppercase letter followed by a lowercase letter\n);\n\n/**\n * Split a string into words. Can deal with camelCase, PascalCase & snake_case.\n * \n * @example\n * splitWords('camelCase')\n * // => ['camel', 'Case']\n * \n * splitWords('PascalCase')\n * // => ['Pascal', 'Case']\n * \n * splitWords('hello_world-123')\n * // => ['hello', 'world', '123']\n * \n * @param str The string to split into words.\n * @returns An array of words.\n */\n\nexport function splitWords(str: string): string[] {\n return str.split(splitWordsRegex).filter(Boolean);\n}","const accentControlRegex = /[\\u0300-\\u036F]/g;\n\n/**\n * Deburrs a string by converting\n * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n * letters to basic Latin letters and removing\n * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n *\n * @example\n * deburr('déjà vu')\n * // => 'deja vu'\n * @param str The string to deburr.\n * @returns Returns the deburred string.\n */\n\nexport function deburr(str: string): string {\n return str.normalize('NFD').replace(accentControlRegex, '');\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts `string` to camelCase.\n *\n * @example\n * camelCase('Foo Bar')\n * // => 'fooBar'\n * camelCase('--foo-bar--')\n * // => 'fooBar'\n * camelCase('__FOO_BAR__')\n * // => 'fooBar'\n * @param str The string to convert.\n * @returns Returns the camel cased string.\n */\n\nexport function camelCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n\n let camelCase = '';\n for (const [index, word] of words.entries()) {\n camelCase += index === 0 \n ? word.toLowerCase() \n : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n }\n\n return camelCase;\n}","/**\n * Converts the first character of a string to upper case and the remaining to lower case.\n *\n * @example\n * capitalize('FRED')\n * // => 'Fred'\n * @param str The string to capitalize.\n * @returns Returns the capitalized string.\n */\n\nexport function capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","const charRegex = /[\"&'<>]/g;\nconst escapeChars = new Map([\n ['&', '&amp;'],\n ['<', '&lt;'],\n ['>', '&gt;'],\n ['\\'', '&#39;'],\n ['\"', '&quot;']\n]);\n\n/**\n * Converts the characters `&`, `<`, `>`, `\"` and `'` in a string to their corresponding HTML entities.\n *\n * @example\n * escapeHtml('fred, barney, & pebbles')\n * // => 'fred, barney, &amp; pebbles'\n * @param str The string to escape.\n * @returns Returns the escaped string.\n */\n\nexport function escapeHtml(str: string): string {\n return str.replace(charRegex, char => escapeChars.get(char)!);\n}\n","const escapleCharsRegex = /[$()*+.?[\\\\\\]^{|}]/g;\n\n/**\n * Escapes the `RegExp` special characters `^`, `$`, `\\`, `.`, `*`, `+`,\n * `?`, `(`, `)`, `[`, `]`, `{`, `}`, and `|` in a string.\n *\n * @example\n * escapeRegExp('[moderndash](https://moderndash.io/)')\n * // => '\\[moderndash\\]\\(https://moderndash\\.io/\\)'\n * @param str The string to escape.\n * @returns Returns the escaped string.\n */\n\nexport function escapeRegExp(str: string): string {\n return str.replace(escapleCharsRegex, '\\\\$&');\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to kebab-case.\n *\n * @example\n * kebabCase('Foo Bar')\n * // => 'foo-bar'\n * kebabCase('fooBar')\n * // => 'foo-bar'\n * kebabCase('__FOO_BAR__')\n * // => 'foo-bar'\n * \n * @param str The string to convert.\n * @returns Returns the kebab cased string.\n */\n\nexport function kebabCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let kebabCase = '';\n for (const word of words) {\n kebabCase += word.toLowerCase() + '-';\n }\n return kebabCase.slice(0, -1);\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n\n/**\n * Converts a string to PascalCase.\n *\n * @example\n * pascalCase('Foo Bar')\n * // => 'FooBar'\n * pascalCase('fooBar')\n * // => 'FooBar'\n * pascalCase('__FOO_BAR__')\n * // => 'FooBar'\n * \n * @param str The string to convert.\n * @returns Returns the pascal cased string.\n */\n\nexport function pascalCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let pascalCase = '';\n for (const word of words) {\n pascalCase += word.charAt(0).toUpperCase() + word.slice(1);\n }\n return pascalCase;\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to snake_case.\n *\n * @example\n * snakeCase('Foo Bar')\n * // => 'foo_bar'\n * snakeCase('fooBar')\n * // => 'foo_bar'\n * snakeCase('--FOO-BAR--')\n * // => 'foo_bar'\n * snakeCase('foo2bar')\n * // => 'foo_2_bar'\n * \n * @param str The string to convert.\n * @returns Returns the snake cased string.\n */\n\nexport function snakeCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let snakeCase = '';\n for (const word of words) {\n if (snakeCase.length > 0) {\n snakeCase += '_';\n }\n snakeCase += word.toLowerCase();\n }\n return snakeCase;\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to Title Case.\n *\n * @example\n * titleCase('--foo-bar--')\n * // => 'Foo Bar'\n * titleCase('fooBar')\n * // => 'Foo Bar'\n * titleCase('__FOO_BAR__')\n * // => 'Foo Bar'\n * titleCase('HélloWorld')\n * // => 'Hello World'\n * @param str The string to convert.\n * @returns Returns the title cased string.\n */\n\nexport function titleCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let titleCase = '';\n for (const word of words) {\n titleCase += word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() + ' ';\n }\n return titleCase.trimEnd();\n}\n","const htmlEntitiesRegex = /&(?:amp|lt|gt|quot|#39);/g;\nconst entityMap = new Map([\n ['&amp;', '&'],\n ['&lt;', '<'],\n ['&gt;', '>'],\n ['&quot;', '\"'],\n ['&#39;', '\\'']\n]);\n\n/**\n * Converts the HTML entities `&amp;`, `&lt;`, `&gt;`, `&quot;` and `&#39;`\n * in a string to their corresponding characters.\n *\n * @example\n * unescapeHtml('fred, barney, &amp; pebbles')\n * // => 'fred, barney, & pebbles'\n * @param str The string to unescape.\n * @returns Returns the unescaped string.\n */\n\nexport function unescapeHtml(str: string): string {\n return str.replace(htmlEntitiesRegex, (entity: string) => entityMap.get(entity)!);\n}\n","/**\n * Checks if `value` is an empty object, collection, map, or set.\n *\n * @example\n * isEmpty(null)\n * // => true\n *\n * isEmpty({})\n * // => true\n *\n * isEmpty(\"\")\n * // => true\n *\n * isEmpty([1, 2, 3])\n * // => false\n *\n * isEmpty('abc')\n * // => false\n *\n * isEmpty({ 'a': 1 })\n * // => false\n * @param value The value to check.\n * @returns Returns `true` if given vlaue is empty, else `false`.\n */\n\nexport function isEmpty(value: string | object | null | undefined): boolean {\n if (value === null || value === undefined) {\n return true;\n }\n\n if (typeof value === 'string' || Array.isArray(value)) {\n return value.length === 0;\n }\n\n if (value instanceof Map || value instanceof Set) {\n return value.size === 0;\n }\n\n if (typeof value === 'object') {\n return Object.keys(value).length === 0;\n }\n\n return false;\n}\n","/* eslint-disable complexity */\nimport type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from './isPlainObject.js';\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * @example\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n * @param a The value to compare.\n * @param b The other value to compare.\n * @returns Returns `true` if the values are equivalent, else `false`.\n */\n\nexport function isEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n \n if (typeof a !== typeof b) return false;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return isSameArray(a, b);\n }\n\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.toString() === b.toString();\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n return isSameObject(a, b);\n }\n\n return false;\n}\n\nfunction isSameObject(a: PlainObject, b: PlainObject) {\n // check if the objects have the same keys\n const keys1 = Object.keys(a);\n const keys2 = Object.keys(b);\n if (!isEqual(keys1, keys2)) return false;\n\n // check if the values of each key in the objects are equal\n for (const key of keys1) {\n if (!isEqual(a[key], b[key])) return false;\n }\n\n // the objects are deeply equal\n return true;\n}\n\nfunction isSameArray(a: unknown[], b: unknown[]) {\n if (a.length !== b.length) return false;\n\n // check if the values of each element in the arrays are equal\n for (const [i, element] of a.entries()) {\n if (!isEqual(element, b[i])) return false;\n }\n\n return true;\n}\n","/**\n * Checks if given string is a valid URL\n *\n * @example\n * isUrl('https://google.com')\n * // => true\n * isUrl('google.com')\n * // => false\n * @param str The string to check.\n * @returns Returns `true` if given string is a valid URL, else `false`.\n */\n\nexport function isUrl(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return false;\n }\n}"],"mappings":"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","names":["difference","intersection","range","range","randomFloat","count","count","retries","timeout","camelCase","kebabCase","pascalCase","snakeCase","titleCase"]}
package/dist/index.d.ts CHANGED
@@ -53,6 +53,9 @@ declare function count<TElem, TKey extends PropertyKey>(array: readonly TElem[],
53
53
  type ArrayMinLength<TElem, TMinLenght extends number> = BuildArrayMinLength<TElem, TMinLenght, []>;
54
54
  type BuildArrayMinLength<TElem, TMinLength extends number, Current extends TElem[]> = Current['length'] extends TMinLength ? [...Current, ...TElem[]] : BuildArrayMinLength<TElem, TMinLength, [...Current, TElem]>;
55
55
 
56
+ type CompareFunction<TArrays extends ArrayMinLength<unknown[], 2>> = (a: TArrays[0][number], b: ArrayTail<TArrays>[number][number]) => boolean;
57
+ type ArrayTail<TArray extends unknown[]> = TArray extends [unknown, ...infer U] ? U : never;
58
+
56
59
  /**
57
60
  * Create a new array with values from the first array that are not present in the other arrays.
58
61
  *
@@ -64,21 +67,22 @@ type BuildArrayMinLength<TElem, TMinLength extends number, Current extends TElem
64
67
  *
65
68
  * // ---- Custom compare function ----
66
69
  * const compareByFloor = (a, b) => Math.floor(a) === Math.floor(b);
67
- * difference(compareByFloor, [1.2, 3.1], [1.3, 2.4])
70
+ * difference([1.2, 3.1], [1.3, 2.4], compareByFloor)
68
71
  * // => [3.1]
69
72
  *
70
73
  * // ---- Only compare by id ----
71
74
  * const arr1 = [{ id: 1, name: 'Yeet' }, { id: 3, name: 'John' }];
72
75
  * const arr2 = [{ id: 3, name: 'Carl' }, { id: 4, name: 'Max' }];
73
76
  *
74
- * difference((a, b) => a.id === b.id, arr1, arr2)
77
+ * difference(arr1, arr2, (a, b) => a.id === b.id)
75
78
  * // => [{ id: 1, name: 'Yeet' }]
76
- * @param arrays First array is inspected, others are excluded.
79
+ * @param arraysOrCompareFn Two or more arrays with an optional compare function at the end.
77
80
  * @template TElem The type of the array elements.
81
+ * @template TArrays The type of the arrays provided.
78
82
  * @returns Returns the new array of filtered values.
79
83
  */
80
- declare function difference<TElem>(...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];
81
- declare function difference<TElem>(arrayOrCompFn: (a: TElem, b: TElem) => boolean, ...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];
84
+ declare function difference<TElem>(...arraysOrCompareFn: ArrayMinLength<TElem[], 2>): TElem[];
85
+ declare function difference<TArrays extends ArrayMinLength<unknown[], 2>>(...arraysOrCompareFn: [...TArrays, CompareFunction<TArrays>]): TArrays[0];
82
86
 
83
87
  /**
84
88
  * Creates a slice of `array` excluding elements dropped from the end.
@@ -138,31 +142,33 @@ declare function dropWhile<TElem>(array: readonly TElem[], predicate: (value: TE
138
142
  declare function group<TElem, TKey extends PropertyKey>(array: readonly TElem[], getGroupKey: (elem: TElem) => TKey): Record<TKey, TElem[]>;
139
143
 
140
144
  /**
141
- * Create an array with unique values from all input arrays, with order based on the first array.
145
+ * Create an array with unique values that are present in all arrays.
146
+ * The order of the values is based on the first array.
142
147
  *
143
148
  * Optionally, use a compare function for element comparison (default is `===`).
144
149
  * @example
145
- * intersection([2, 1], [2, 3])
150
+ * intersection([2, 1], [2, 3], [6, 2])
146
151
  * // => [2]
147
152
  *
148
153
  * // ---- Custom compare function ----
149
154
  * const compareFn = (a, b) => Math.floor(a) === Math.floor(b);
150
155
  *
151
- * intersection(compareFn, [1.2, 1.1], [1.3, 2.4])
156
+ * intersection([1.2, 1.1], [1.3, 2.4], compareFn)
152
157
  * // => [1.2]
153
158
  *
154
159
  * // ---- Only compare by id ----
155
160
  * const arr1 = [{ id: 1, name: 'Yeet' }, { id: 3, name: 'John' }];
156
161
  * const arr2 = [{ id: 3, name: 'Carl' }, { id: 4, name: 'Max' }];
157
162
  *
158
- * intersection((a, b) => a.id === b.id, arr1, arr2)
163
+ * intersection(arr1, arr2, (a, b) => a.id === b.id)
159
164
  * // => [{ id: 3, name: 'John' }]
160
- * @param arrays The arrays to inspect.
165
+ * @param arraysOrCompareFn Two or more arrays with an optional compare function at the end.
161
166
  * @template TElem The type of the array elements.
167
+ * @template TArrays The type of the arrays provided.
162
168
  * @returns Returns the new array of intersecting values.
163
169
  */
164
- declare function intersection<TElem>(...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];
165
- declare function intersection<TElem>(arrayOrCompFn: (a: TElem, b: TElem) => boolean, ...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];
170
+ declare function intersection<TElem>(...arraysOrCompareFn: ArrayMinLength<TElem[], 2>): TElem[];
171
+ declare function intersection<TArrays extends ArrayMinLength<unknown[], 2>>(...arraysOrCompareFn: [...TArrays, CompareFunction<TArrays>]): TArrays[0];
166
172
 
167
173
  /**
168
174
  * Generates an iterable sequence of numbers starting from `start`, up to and including `end`,
@@ -809,7 +815,7 @@ type PlainObject = Record<PropertyKey, unknown>;
809
815
  * Flattens an object into a single level object.
810
816
  *
811
817
  * @example
812
- * const obj = { a: { b: 2, c: [{ d: 3 }, {d: 4 }] } };
818
+ * const obj = { a: { b: 2, c: [{ d: 3 }, { d: 4 }] } };
813
819
  * flatKeys(obj);
814
820
  * // => { 'a.b': 2, 'a.c[0].d': 3, 'a.c[1].d': 4 }
815
821
  *
package/dist/index.js CHANGED
@@ -33,18 +33,19 @@ function fastArrayFlat(arrays) {
33
33
  }
34
34
 
35
35
  // src/array/difference.ts
36
- function difference(arrayOrCompFn, ...arrays) {
37
- const withCompareFn = typeof arrayOrCompFn === "function";
38
- const firstArray = withCompareFn ? arrays.shift() : arrayOrCompFn;
36
+ function difference(...arraysOrCompareFn) {
37
+ const compareFnProvided = typeof arraysOrCompareFn.at(-1) === "function";
38
+ const compareFunction = compareFnProvided && arraysOrCompareFn.pop();
39
+ const arrays = arraysOrCompareFn;
40
+ const firstArray = arrays.shift();
39
41
  const combinedRestArray = fastArrayFlat(arrays);
40
- if (!withCompareFn) {
42
+ if (!compareFunction) {
41
43
  const restSet = new Set(combinedRestArray);
42
44
  return firstArray.filter((element) => !restSet.has(element));
43
45
  }
44
- const compareFN = arrayOrCompFn;
45
46
  const difference2 = [];
46
47
  for (const element of firstArray) {
47
- if (combinedRestArray.every((item) => !compareFN(item, element))) {
48
+ if (combinedRestArray.every((item) => !compareFunction(element, item))) {
48
49
  difference2.push(element);
49
50
  }
50
51
  }
@@ -96,18 +97,19 @@ function unique(array, compareFn) {
96
97
  }
97
98
 
98
99
  // src/array/intersection.ts
99
- function intersection(arrayOrCompFn, ...arrays) {
100
- const withCompareFn = typeof arrayOrCompFn === "function";
101
- const firstArray = unique(withCompareFn ? arrays.shift() : arrayOrCompFn);
100
+ function intersection(...arraysOrCompareFn) {
101
+ const compareFnProvided = typeof arraysOrCompareFn.at(-1) === "function";
102
+ const compareFunction = compareFnProvided && arraysOrCompareFn.pop();
103
+ const arrays = arraysOrCompareFn;
104
+ const firstArray = unique(arrays.shift());
102
105
  const combinedRestArray = fastArrayFlat(arrays);
103
- if (!withCompareFn) {
106
+ if (!compareFunction) {
104
107
  const restSet = new Set(combinedRestArray);
105
108
  return firstArray.filter((element) => restSet.has(element));
106
109
  }
107
- const compareFN = arrayOrCompFn;
108
110
  const intersection2 = [];
109
111
  for (const element of firstArray) {
110
- if (combinedRestArray.some((item) => compareFN(item, element))) {
112
+ if (combinedRestArray.some((item) => compareFunction(element, item))) {
111
113
  intersection2.push(element);
112
114
  }
113
115
  }
@@ -662,13 +664,11 @@ function deburr(str) {
662
664
  function camelCase(str) {
663
665
  str = deburr(str);
664
666
  const words = splitWords(str);
665
- const camelCase2 = words.map((word, index) => {
666
- if (index === 0) {
667
- return word.toLowerCase();
668
- }
669
- return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
670
- });
671
- return camelCase2.join("");
667
+ let camelCase2 = "";
668
+ for (const [index, word] of words.entries()) {
669
+ camelCase2 += index === 0 ? word.toLowerCase() : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
670
+ }
671
+ return camelCase2;
672
672
  }
673
673
 
674
674
  // src/string/capitalize.ts
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/array/chunk.ts","../src/array/count.ts","../src/helpers/fastArrayFlat.ts","../src/array/difference.ts","../src/array/dropRightWhile.ts","../src/array/dropWhile.ts","../src/array/group.ts","../src/array/unique.ts","../src/array/intersection.ts","../src/array/range.ts","../src/array/shuffle.ts","../src/array/sort.ts","../src/array/takeRightWhile.ts","../src/array/takeWhile.ts","../src/crypto/hash.ts","../src/crypto/randomInt.ts","../src/crypto/randomElem.ts","../src/crypto/randomFloat.ts","../src/crypto/randomString.ts","../src/decorator/toDecorator.ts","../src/function/debounce.ts","../src/decorator/decDebounce.ts","../src/function/maxCalls.ts","../src/decorator/decMaxCalls.ts","../src/function/memoize.ts","../src/decorator/decMemoize.ts","../src/function/minCalls.ts","../src/decorator/decMinCalls.ts","../src/function/throttle.ts","../src/decorator/decThrottle.ts","../src/function/times.ts","../src/number/sum.ts","../src/number/average.ts","../src/number/median.ts","../src/number/round.ts","../src/validate/isPlainObject.ts","../src/object/flatKeys.ts","../src/object/merge.ts","../src/object/pick.ts","../src/object/omit.ts","../src/object/set.ts","../src/promise/queue.ts","../src/promise/races.ts","../src/promise/sleep.ts","../src/promise/retry.ts","../src/promise/timeout.ts","../src/promise/tryCatch.ts","../src/string/splitWords.ts","../src/string/deburr.ts","../src/string/camelCase.ts","../src/string/capitalize.ts","../src/string/escapeHtml.ts","../src/string/escapeRegExp.ts","../src/string/kebabCase.ts","../src/string/pascalCase.ts","../src/string/snakeCase.ts","../src/string/titleCase.ts","../src/string/unescapeHtml.ts","../src/validate/isEmpty.ts","../src/validate/isEqual.ts","../src/validate/isUrl.ts"],"sourcesContent":["/**\n * Creates an array of elements split into groups the length of size. If array can't be split evenly, the final chunk will be the remaining elements.\n *\n * @example\n * chunk(['a', 'b', 'c', 'd'], 2)\n * // => [['a', 'b'], ['c', 'd']]\n *\n * chunk(['a', 'b', 'c', 'd'], 3)\n * // => [['a', 'b', 'c'], ['d']]\n * @param chunkSize The length of each chunk\n * @param array The array to chunk.\n * @template TElem The type of the array elements.\n * @returns Returns the new array of chunks.\n */\n\nexport function chunk<TElem>(array: readonly TElem[], chunkSize: number): TElem[][] {\n const intSize = Math.trunc(chunkSize);\n if (array.length === 0 || intSize < 1) {\n return [];\n }\n \n let index = 0;\n let resultIndex = 0;\n const result = new Array(Math.ceil(array.length / intSize)) as TElem[][];\n\n while (index < array.length) {\n result[resultIndex++] = array.slice(index, (index += intSize));\n }\n\n return result;\n}\n","/**\n * Creates an object with counts of occurrences of items in the array.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true, age: 36 },\n * { 'user': 'betty', 'active': false, age: 36 },\n * { 'user': 'fred', 'active': true, age: 40 }\n * ]\n *\n * count(users, value => value.active ? 'active' : 'inactive');\n * // => { 'active': 2, 'inactive': 1 }\n *\n * count(users, value => value.age);\n * // => { 36: 2, 40: 1 }\n *\n * @param criteria The criteria to count by.\n * @param array The array or record to iterate over.\n * @template TElem The type of the array elements.\n * @returns Returns the composed aggregate object.\n */\n\nexport function count<TElem, TKey extends PropertyKey>(array: readonly TElem[], criteria: (value: TElem) => TKey): Record<TKey, number> {\n const result = {} as Record<TKey, number>;\n for (const value of array) {\n const key = criteria(value);\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n result[key] = (result[key] ?? 0) + 1;\n }\n return result;\n}","// native array.flat is much slower than this - node 19\nexport function fastArrayFlat<TElem>(arrays: (readonly TElem[])[]): readonly TElem[] {\n let result = arrays.shift() ?? [];\n\n for (const array of arrays) {\n result = [...result, ...array];\n }\n\n return result;\n}","import type { ArrayMinLength } from '@type/ArrayMinLength.js';\n\nimport { fastArrayFlat } from '@helpers/fastArrayFlat.js';\n\n/**\n * Create a new array with values from the first array that are not present in the other arrays.\n * \n * Optionally, use a compare function to determine the comparison of elements (default is `===`).\n * \n * @example\n * difference([2, 1], [2, 3], [6])\n * // => [1]\n *\n * // ---- Custom compare function ----\n * const compareByFloor = (a, b) => Math.floor(a) === Math.floor(b);\n * difference(compareByFloor, [1.2, 3.1], [1.3, 2.4])\n * // => [3.1]\n *\n * // ---- Only compare by id ----\n * const arr1 = [{ id: 1, name: 'Yeet' }, { id: 3, name: 'John' }];\n * const arr2 = [{ id: 3, name: 'Carl' }, { id: 4, name: 'Max' }];\n *\n * difference((a, b) => a.id === b.id, arr1, arr2)\n * // => [{ id: 1, name: 'Yeet' }]\n * @param arrays First array is inspected, others are excluded.\n * @template TElem The type of the array elements.\n * @returns Returns the new array of filtered values.\n */\n\nexport function difference<TElem>(...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];\nexport function difference<TElem>(arrayOrCompFn: (a: TElem, b: TElem) => boolean, ...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];\nexport function difference<TElem>(arrayOrCompFn: readonly TElem[] | ((a: TElem, b: TElem) => boolean), ...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[] {\n const withCompareFn = typeof arrayOrCompFn === 'function';\n const firstArray = withCompareFn ? arrays.shift()! : arrayOrCompFn;\n const combinedRestArray = fastArrayFlat(arrays);\n\n if (!withCompareFn) {\n const restSet = new Set(combinedRestArray);\n return firstArray.filter(element => !restSet.has(element));\n }\n\n const compareFN = arrayOrCompFn as (a: TElem, b: TElem) => boolean;\n const difference: TElem[] = [];\n for (const element of firstArray) {\n if (combinedRestArray.every(item => !compareFN(item, element))) {\n difference.push(element);\n }\n }\n\n return difference;\n}\n","/**\n * Creates a slice of `array` excluding elements dropped from the end. \n * Elements are dropped until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': true }\n * ]\n *\n * dropRightWhile(users, user => user.active)\n * // => objects for ['barney']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function dropRightWhile<TElem>(array: readonly TElem[], predicate: (value: TElem) => boolean) {\n let i = array.length;\n while (i > 0 && predicate(array[i - 1])) {\n i--;\n }\n return array.slice(0, i);\n}\n","/**\n * Creates a slice of `array` excluding elements dropped from the beginning. \n * Elements are dropped until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': false }\n * ]\n *\n * dropWhile(users, user => user.active)\n * // => objects for ['pebbles']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function dropWhile<TElem>(array: readonly TElem[], predicate: (value: TElem) => boolean): TElem[] {\n const index = array.findIndex(x => !predicate(x));\n return array.slice(index === -1 ? array.length : index);\n}\n","/**\n * Creates an object with grouped items in the array.\n *\n * @example\n * group([6.1, 4.2, 6.3], Math.floor)\n * // => { 4: [4.2], 6: [6.1, 6.3] }\n *\n * group([6.1, 4.2, 6.3], value => value > 5 ? '>5' : '<=5')\n * // => { '<=5': [4.2], '>5': [6.1, 6.3] }\n * \n * @param collection The array or object to iterate over.\n * @param getGroupKey A function that returns the group id for each item.\n * @template TElem The type of the array elements.\n * @returns An object with grouped items.\n */\n\nexport function group<TElem, TKey extends PropertyKey>(array: readonly TElem[], getGroupKey: (elem: TElem) => TKey): Record<TKey, TElem[]> {\n const result = {} as Record<TKey, TElem[]>;\n for (const elem of array) {\n const key = getGroupKey(elem);\n (result[key] ??= []).push(elem);\n }\n return result;\n}","/**\n * Creates a duplicate-free version of an array, in which only the first occurrence of each element is kept. \n * The order of result values is determined by the order they occur in the array.\n *\n * A compare function is optional to specify how the array is compared (default is `===`).\n * \n * @example\n * unique([2, 1, 2])\n * // => [2, 1]\n * \n * // compare by object values\n * const users = [\n * { id: 1, name: 'john' },\n * { id: 2, name: 'john' },\n * { id: 2, name: 'john' },\n * ]\n * \n * unique(users, isEqual)\n * // => [{ id: 1, name: 'john' }, { id: 2, name: 'john' }]\n * \n * // compare by id\n * unique(users, (a, b) => a.name === b.name)\n * // => [{ id: 1, name: 'john' }]\n *\n * @param array The array to inspect.\n * @param iteratee The iteratee invoked per element.\n * @template TElem The type of the array elements.\n * @returns Returns the new duplicate free array.\n */\n\nexport function unique<TElem>(array: readonly TElem[], compareFn?: (a: TElem, b: TElem) => boolean): TElem[] {\n // Arrays optimized with native Set\n if (!compareFn)\n return [...new Set(array)];\n\n const uniqueArray: TElem[] = [];\n for (const value of array) {\n let isUnique = true;\n \n for (const uniqueValue of uniqueArray) {\n if (compareFn(value, uniqueValue)) {\n isUnique = false;\n break;\n }\n }\n \n if (isUnique)\n uniqueArray.push(value);\n }\n \n return uniqueArray;\n}\n","import type { ArrayMinLength } from '@type/ArrayMinLength.js';\n\nimport { fastArrayFlat } from '@helpers/fastArrayFlat.js';\n\nimport { unique } from './unique.js';\n\n/**\n * Create an array with unique values from all input arrays, with order based on the first array. \n * \n * Optionally, use a compare function for element comparison (default is `===`).\n * @example\n * intersection([2, 1], [2, 3])\n * // => [2]\n *\n * // ---- Custom compare function ----\n * const compareFn = (a, b) => Math.floor(a) === Math.floor(b);\n * \n * intersection(compareFn, [1.2, 1.1], [1.3, 2.4])\n * // => [1.2]\n *\n * // ---- Only compare by id ----\n * const arr1 = [{ id: 1, name: 'Yeet' }, { id: 3, name: 'John' }];\n * const arr2 = [{ id: 3, name: 'Carl' }, { id: 4, name: 'Max' }];\n *\n * intersection((a, b) => a.id === b.id, arr1, arr2)\n * // => [{ id: 3, name: 'John' }]\n * @param arrays The arrays to inspect.\n * @template TElem The type of the array elements.\n * @returns Returns the new array of intersecting values.\n */\n\nexport function intersection<TElem>(...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];\nexport function intersection<TElem>(arrayOrCompFn: (a: TElem, b: TElem) => boolean, ...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[];\nexport function intersection<TElem>(arrayOrCompFn: readonly TElem[] | ((a: TElem, b: TElem) => boolean), ...arrays: ArrayMinLength<readonly TElem[], 2>): TElem[] {\n const withCompareFn = typeof arrayOrCompFn === 'function';\n const firstArray = unique(withCompareFn ? arrays.shift()! : arrayOrCompFn);\n const combinedRestArray = fastArrayFlat(arrays);\n\n if (!withCompareFn) {\n const restSet = new Set(combinedRestArray);\n return firstArray.filter(element => restSet.has(element));\n }\n \n const compareFN = arrayOrCompFn as (a: TElem, b: TElem) => boolean;\n const intersection: TElem[] = [];\n\n for (const element of firstArray) {\n if (combinedRestArray.some(item => compareFN(item, element))) {\n intersection.push(element);\n }\n }\n\n return intersection;\n}\n","/**\n * Generates an iterable sequence of numbers starting from `start`, up to and including `end`,\n * with a given `step` between each number.\n *\n * @example\n * for (const num of range(1, 5)) {\n * console.log(num);\n * }\n * // => 1 2 3 4 5\n * \n * // Generate an array of even numbers between 0 and 10:\n * const arr = [...range(0, 10, 2)];\n * // => [0, 2, 4, 6, 8, 10]\n * \n * @param start The starting number of the sequence.\n * @param end The end number of the sequence.\n * @param step The step between each number in the sequence. Defaults to 1.\n *\n * @returns An iterable sequence of numbers between `start` and `end`, inclusive, with increments of `step`.\n */\nexport function* range(start: number, end: number, step = 1): Generator<number> {\n if (start > end)\n throw new Error('The start of the range must be less than or equal to the end.');\n\n if (step <= 0)\n throw new Error('The step must be greater than 0.');\n \n for (let i = start; i <= end; i += step) {\n yield i;\n }\n}","/**\n * Creates a new array of shuffled values, using the Fisher-Yates-Durstenfeld Shuffle algorithm.\n *\n * @example\n * shuffle([1, 2, 3, 4])\n * // => [4, 1, 3, 2]\n * @param array The array or object to shuffle.\n * @template TElem The type of the array elements.\n * @returns Returns a new shuffled array.\n */\n\nexport function shuffle<TElem>(array: readonly TElem[]): TElem[] {\n const shuffledArray = [...array];\n \n for (let index = shuffledArray.length - 1; index > 0; index--) {\n const randomIndex = Math.floor(Math.random() * (index + 1));\n [shuffledArray[index], shuffledArray[randomIndex]] = [shuffledArray[randomIndex], shuffledArray[index]];\n }\n \n return shuffledArray;\n}","\n/**\n * Creates a new sorted array in ascending or descending order based on one or multiple sorting criteria.\n * \n * @example\n * sort([1, 2, 3, 4], { order: 'desc' })\n * // => [4, 3, 2, 1]\n * \n * // --- Sorting by multiple properties ---\n * const array = [{ a: 2, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 1 }];\n * \n * sort(array,\n * { order: 'asc', by: item => item.a },\n * { order: 'desc', by: item => item.b }\n * )\n * // => [{ a: 1, b: 2 }, { a: 1, b: 1 }, { a: 2, b: 1 }]\n * @param array The array to sort.\n * @param orders The sorting criteria, one or multiple objects with properties order (either 'asc' or 'desc') and by (iteratee function to sort based on a specific property).\n * @param orders.order - The order to sort in, either 'asc' or 'desc'.\n * @param orders.by - The iteratee function to sort based on a specific property.\n * @template TElem The type of the array elements.\n * @returns Returns a new sorted array.\n*/\nexport function sort<TElem>(array: readonly TElem[], ...orders: { order?: 'asc' | 'desc', by?: (item: TElem) => number | bigint | Date | string }[]): TElem[] {\n return [...array].sort((a, b) => {\n for (const { order, by } of orders) {\n const aValue = by ? by(a) : a;\n const bValue = by ? by(b) : b;\n if (aValue < bValue) {\n return order === 'desc' ? 1 : -1; \n }\n if (aValue > bValue) {\n return order === 'desc' ? -1 : 1;\n }\n }\n return 0;\n });\n}","/**\n * Creates a slice of `array` with elements taken from the end. \n * Elements are taken until `predicate` returns falsey.\n * \n * @example\n * const users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': true }\n * ]\n *\n * takeRightWhile(users, user => user.active)\n * // => objects for ['fred', 'pebbles']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function takeRightWhile<TElem>(array: readonly TElem[], predicate: (elem: TElem) => boolean): TElem[] {\n const result: TElem[] = [];\n\n for (let i = array.length - 1; i >= 0; i--) {\n if (predicate(array[i])) {\n result.unshift(array[i]);\n } else {\n break;\n }\n }\n\n return result;\n}\n","/**\n * Creates a slice of `array` with elements taken from the beginning. \n * Elements are taken until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': false }\n * ]\n *\n * takeWhile(users, user => user.active)\n * // => objects for ['barney', 'fred']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function takeWhile<TElem>(array: readonly TElem[], predicate: (elem: TElem) => boolean): TElem[] {\n const result: TElem[] = [];\n\n for (const element of array) {\n if (predicate(element)) {\n result.push(element);\n } else {\n break;\n }\n }\n\n return result;\n}\n","import type { Jsonifiable } from '@type/Jsonifiable.js';\n\ntype SupportedAlgorithms = 'SHA-256' | 'SHA-384' | 'SHA-512';\n\nlet textEncoder: TextEncoder | undefined;\n\n/**\n * Generates a hash from the given data using the specified algorithm.\n *\n * It uses the Web Crypto API to generate the hash.\n * \n * *Note: If you need a secure hash use a specialized library like [crypto-js](https://www.npmjs.com/package/crypto-js) instead.*\n * \n * @example\n * // Hash a string using the default algorithm (SHA-256)\n * await hash('hello world'); \n * // => \"b94d27b9934d3e08a52e52d7da7dabfac484efe37a53...\"\n *\n * // Hash an object using the SHA-512 algorithm\n * await hash({ foo: 'bar', baz: 123 }, 'SHA-512');\n * // => \"d8f3c752c6820e580977099368083f4266b569660558...\"\n * \n * @param data The data to hash, either as a string or a JSON-serializable object.\n * @param algorithm The hashing algorithm to use. Defaults to 'SHA-256'.\n * @returns A Promise that resolves to the hexadecimal representation of the hash.\n *\n * @throws {DOMException} If the specified algorithm is not supported by the Web Crypto API.\n */\n\nexport async function hash(data: Jsonifiable, algorithm: SupportedAlgorithms = 'SHA-256'): Promise<string> {\n textEncoder ??= new TextEncoder();\n\n const dataBuffer = typeof data === 'string'\n ? textEncoder.encode(data) \n : textEncoder.encode(JSON.stringify(data));\n \n const hashBuffer = await crypto.subtle.digest(algorithm, dataBuffer);\n const hashArray = [...new Uint8Array(hashBuffer)];\n const hexValues = hashArray.map(b => b.toString(16).padStart(2, '0'));\n return hexValues.join('');\n}\n","\n/**\n * Generates a random integer between two given numbers, including those numbers.\n * \n * It uses `crypto.getRandomValues` to generate the random number.\n * @example\n * randomInt(1, 10) \n * // => 5\n * \n * @param min The smallest integer that can be generated.\n * @param max The largest integer that can be generated.\n * \n * @returns A random integer between `min` and `max`, including `min` and `max`.\n */\n\nexport function randomInt(min: number, max: number): number {\n // Taken from https://stackoverflow.com/a/41452318\n if (!Number.isInteger(min) || !Number.isInteger(max))\n throw new TypeError('min and max must be integers');\n\n if (min >= max) \n throw new Error('max must be greater than min');\n\n const range = max - min + 1;\n const randomBytes = Math.ceil(Math.log2(range) / 8);\n const maxRandNumber = Math.pow(256, randomBytes);\n const randomBuffer = new Uint8Array(randomBytes);\n\n let randomValue: number;\n do {\n crypto.getRandomValues(randomBuffer);\n randomValue = 0;\n for (let index = 0; index < randomBytes; index++) {\n // eslint-disable-next-line no-bitwise\n randomValue = (randomValue << 8) + randomBuffer[index];\n }\n // rerun if randomValue is bigger than range\n } while (randomValue >= maxRandNumber - (maxRandNumber % range));\n\n return min + (randomValue % range);\n}\n","import { randomInt } from './randomInt.js';\n\n/**\n * Gets a random element an array. A single element is returned by default. \n * Specify the `multi` parameter to get an array of multiple random elements.\n *\n * If the array is empty, `undefined` is returned. \n * If `multi` is defined it returns an empty array.\n * \n * It uses `crypto.getRandomValues` to get the random element.\n * @example\n * randomElem([1, 2, 3, 4])\n * // => 2\n *\n * randomElem([1, 2, 3, 4], 2)\n * // => [3, 1]\n * @param array The array to sample.\n * @returns Returns the random element.\n */\n\nexport function randomElem<TArr>(array: TArr[]): TArr | undefined;\nexport function randomElem<TArr>(array: TArr[], multi: number): TArr[];\nexport function randomElem<TArr>(array: TArr[], multi?: number): TArr | undefined | TArr[] {\n if (multi === undefined) {\n if (array.length === 0) return undefined;\n return getSingleElement(array);\n }\n\n if (multi && array.length === 0) return [];\n\n // Multiple samples\n const result = new Array<TArr>(multi);\n for (let i = 0; i < multi; i++) {\n result[i] = getSingleElement(array);\n }\n return result;\n}\n\nfunction getSingleElement<TArr>(array: TArr[]): TArr {\n const randomIndex = randomInt(0, array.length - 1);\n return array[randomIndex];\n}","/* eslint-disable no-bitwise */\nconst shiftLeft20Bits = 2 ** 20;\nconst shiftRight52Bits = 2 ** -52;\n\n/**\n * Generates a random float between two given numbers, including those numbers.\n * \n * It uses `crypto.getRandomValues` to generate the random number.\n * @example\n * randomFloat(1, 10) \n * // => 1.123456789\n * \n * @param min The smallest float that can be generated.\n * @param max The largest float that can be generated.\n * \n * @returns A random float between `min` and `max`, including `min` and `max`.\n */\n\nexport function randomFloat(min: number, max: number): number {\n if (min >= max) {\n throw new Error('max must be greater than min');\n }\n const range = max - min;\n const randomBuffer = new Uint32Array(2);\n crypto.getRandomValues(randomBuffer);\n\n // keep all 32 bits of the the first, top 20 of the second for 52 random bits\n const mantissa = (randomBuffer[0] * shiftLeft20Bits) + (randomBuffer[1] >>> 12);\n\n // shift all 52 bits to the right of the decimal point\n const randomFloat = mantissa * shiftRight52Bits;\n return min + (randomFloat * range);\n}","import { randomInt } from './randomInt.js';\n\nconst DEFAULT_CHARSET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n\n/**\n * Generates a random string of the specified length.\n * The default charset is alphanumeric characters.\n * \n * It uses `crypto.getRandomValues` to generate the random string.\n * \n * @example\n * randomString(8);\n * // => \"JWw1p6rD\"\n *\n * randomString(16, 'abc');\n * // => \"cbaacbabcabccabc\"\n * @param length The length of the string to generate.\n * @param charSet The set of characters to use when generating the string. Defaults to alphanumeric characters.\n * @returns A random string of the specified length.\n */\n\nexport function randomString(length: number, charSet = DEFAULT_CHARSET): string {\n if (charSet.length <= 0) return '';\n\n let result = '';\n for (let index = 0; index < length; index++) {\n const randomIndex = randomInt(0, charSet.length - 1);\n result += charSet[randomIndex];\n }\n\n return result;\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\ntype Tail<T extends unknown[]> = T extends [infer _Head, ...infer Tail] ? Tail : never;\n\n/**\n * Transforms a function that takes a function as first argument into a decorator function.\n * \n * @example\n * ```typescript\n * function log(func: Function, message: string) {\n * return function (...args: unknown[]) {\n * console.log(message);\n * return func(...args);\n * };\n * }\n * \n * const logger = toDecorator(log);\n * \n * class TestClass {\n * @logger(\"Hello world!\")\n * testMethod() {\n * return 1; \n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(); \n * // => Log \"Hello World\" and return 1\n * ```\n * @param func The function to transform.\n * @returns A decorator function that can be used to decorate a method.\n */\n\nexport function toDecorator<TFunc extends GenericFunction<TFunc>>(func: TFunc) {\n return function (...args: Tail<Parameters<TFunc>>) {\n return function (target: unknown, key: string, descriptor: PropertyDescriptor) {\n const creatorArgs = [descriptor.value, ...args] as Parameters<TFunc>;\n descriptor.value = func(...creatorArgs);\n };\n };\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a debounced version of a function. Only calling it after a specified amount of time has passed without any new calls.\n * \n * **Methods:** \n * - `cancel` will cancel the next invocation of the debounced function. \n * - `flush` will immediately invoke the debounced function and cancel any pending invocations. \n * \n * This function can be used as a decorator with {@link decDebounce}.\n * \n * @example\n * const sayHello = (name: string) => console.log(`Hello, ${name}!`);\n * const debouncedSayHello = debounce(sayHello, 200);\n * \n * debouncedSayHello(\"John\");\n * debouncedSayHello(\"Jane\");\n * // => Only the second invocation of `debouncedSayHello` is executed, after a delay of 200ms.\n * @param func The function to debounce.\n * @param wait The number of milliseconds to wait before invoking `func`.\n * @returns A debounced version of `func` with `cancel` and `flush` methods.\n */\n\nexport function debounce<TFunc extends GenericFunction<TFunc>>(func: TFunc, wait: number): TFunc & {\n cancel: () => void;\n flush: () => void;\n} {\n let timeoutId: NodeJS.Timeout | undefined;\n const debounced = function (this: unknown, ...args: Parameters<TFunc>) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => func.apply(this, args), wait);\n };\n\n /** Cancels the next invocation of the debounced function. */\n debounced.cancel = function () {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n };\n\n /** Immediately invokes the debounced function and cancels any pending invocations. */\n debounced.flush = function (this: unknown, ...args: Parameters<TFunc>) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n func.apply(this, args);\n };\n\n return debounced as TFunc & { cancel: () => void; flush: () => void };\n}","import { toDecorator } from '@decorator/toDecorator.js';\nimport { debounce } from '@function/debounce.js';\n\n/**\n * Debouces the decorated function. Only calling it after a specified amount of time has passed without any new calls.\n * \n * Look at {@link debounce} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decDebounce(100)\n * testMethod(str: string) {\n * console.log(\"Debounced:\", str);\n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(\"Hello\");\n * instance.testMethod(\"World\");\n * // => Only the second invocation of `debouncedSayHello` is executed, after a delay of 1000ms.\n * ```\n * @param wait Milliseconds to wait before invoking the decorated function after the last invocation.\n */\n\nexport function decDebounce(wait: number) {\n return toDecorator(debounce)(wait);\n}\n","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a function that invokes the given function as long as it's called `<= n` times.\n * \n * Subsequent calls to the created function return the result of the last `func` invocation.\n *\n * This function can be used as a decorator with {@link decMaxCalls}.\n * @example\n * let count = 0;\n * const addCount = () => ++count;\n *\n * // Allow addCount to be invoked twice.\n * const limitAddCount = maxCalls(addCount, 2)\n *\n * limitAddCount() // => 1\n * limitAddCount() // => 2\n * limitAddCount() // => 2\n * // => `limitAddCount` is invoked twice and the result is cached.\n * @param n The number of calls before the cached result is returned.\n * @param func The function to restrict.\n * @returns Returns the new restricted function.\n */\n\nexport function maxCalls<TFunc extends GenericFunction<TFunc>>(func: TFunc, n: number): TFunc {\n let count = 0;\n let result: ReturnType<TFunc>;\n return function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> {\n if (count < n) {\n count += 1;\n result = func.apply(this, args);\n }\n return result;\n } as TFunc;\n}\n","import { toDecorator } from '@decorator/toDecorator.js';\nimport { maxCalls } from '@function/maxCalls.js';\n\n/**\n * Only invokes the decorated function as long as it's called `<= n` times. \n * Subsequent calls to the decorated function return the result of the last invocation.\n * \n * Look at {@link maxCalls} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * private count = 0;\n * @decMaxCalls(2)\n * testMethod() {\n * return ++this.count;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(); // => 1 \n * instance.testMethod(); // => 2\n * instance.testMethod(); // => 2\n * ```\n * @param n The number of calls before the cached result is returned.\n */\n\nexport function decMaxCalls(n: number) {\n return toDecorator(maxCalls)(n);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\nconst defaultResolver = (...args: unknown[]) => JSON.stringify(args);\n\n/**\n * Creates a function that memoizes the result of a given function.\n * \n * The cache key is determined by the `resolver` or by the arguments from the function call.\n *\n * **Options:**\n * - `resolver` A function that determines the cache key based on the arguments provided.\n * - `ttl` the time to live for the cache entries in milliseconds.\n * \n * **Properties:**\n * - `cache` The cache is an instance of `Map` and can be used to clear or inspect the cache. \n * It can be replaced by a custom cache that matches the `Map` interface.\n * \n * \n * This function can be used as a decorator with {@link decMemoize}.\n * \n * @example\n * ```typescript\n * function fibonacci(n: number) {\n * if (n <= 1) return n;\n * return fibonacci(n - 1) + fibonacci(n - 2);\n * }\n *\n * const memoizedFib = memoize(fibonacci, { ttl: 1000 })\n * \n * memoizedFib(40) // => 102334155\n * memoizedFib(40) // => 102334155 (cache hit)\n * setTimeout(() => memoizedFib(40), 1000) // => 102334155 (cache miss)\n * \n * // Cached values are exposed as the `cache` property.\n * memoizedFib.cache.get(\"40\") // => [value, timestamp]\n * memoizedFib.cache.set(\"40\", [1234, Date.now()])\n * memoizedFib.cache.clear()\n * \n * // This is the default way to create cache keys.\n * const defaultResolver = (...args: unknown[]) => JSON.stringify(args)\n * ```\n * @param func The function to have its output memoized.\n * @param options The options object with optional `resolver` and `ttl` parameters.\n * @param options.resolver - A function that determines the cache key for storing the result based on the arguments provided.\n * @param options.ttl - The time to live for the cache in milliseconds.\n * @template TFunc The type of the function to memoize.\n * @template Cache The type of the cache storage.\n * @returns Returns the new memoized function.\n */\n\nexport function memoize<TFunc extends GenericFunction<TFunc>, Cache extends Map<string, [ReturnType<TFunc>, number]>>(\n func: TFunc, options: { resolver?: (...args: Parameters<TFunc>) => string, ttl?: number; } = {}\n): TFunc & { cache: Cache } {\n const resolver = options.resolver ?? defaultResolver;\n const ttl = options.ttl;\n const cache = new Map() as Cache;\n\n const memoizedFunc = function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> {\n const key = resolver(...args);\n if (cache.has(key)) {\n const [cacheResult, cacheTime] = cache.get(key)!;\n if (ttl === undefined || (Date.now() - cacheTime < ttl)) {\n return cacheResult;\n }\n }\n const result = func.apply(this, args);\n cache.set(key, [result, Date.now()]);\n return result;\n };\n\n memoizedFunc.cache = cache;\n return memoizedFunc as TFunc & { cache: Cache };\n} ","import { toDecorator } from '@decorator/toDecorator.js';\nimport { memoize } from '@function/memoize.js';\n\n/**\n * Memoizes the decorated function. \n * The cache key is either determined by the provided resolver or by the arguments used in the memoized function.\n * \n * **Options:**\n * - `resolver` A function that determines the cache key for storing the result based on the arguments provided.\n * - `ttl` sets the time to live for the cache in milliseconds. After `ttl` milliseconds, the next call to the memoized function will result in a cache miss.\n * \n * Look at {@link memoize} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decMemoize({ ttl: 1000 })\n * testMethod(a: number, b: number) {\n * return a + b;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(1, 2); // => 3\n * instance.testMethod(1, 2); // => 3 (cached)\n * \n * // After 1 second:\n * instance.testMethod(1, 2); // => 3 (cache miss)\n * ```\n * @param options The options object.\n * @param options.resolver - A function that determines the cache key for storing the result based on the arguments provided.\n * @param options.ttl - The time to live for the cache in milliseconds.\n */\n\nexport function decMemoize(options: Parameters<typeof memoize>[1] = {}) {\n return toDecorator(memoize)(options);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a function that invokes the given function once it's called more than `n` times. \n * Returns undefined until the minimum call count is reached.\n * \n * This function can be used as a decorator with {@link decMinCalls}.\n * @example\n * const caution = () => console.log(\"Caution!\");\n * const limitedCaution = minCalls(caution, 2);\n *\n * limitedCaution()\n * limitedCaution()\n * limitedCaution()\n * // => `caution` is invoked on the third call.\n * @param n The number of calls before the given function is invoked.\n * @param func The function to restrict.\n * @returns Returns the new restricted function.\n */\n\nexport function minCalls<TFunc extends GenericFunction<TFunc>>(func: TFunc, n: number) {\n let count = 1;\n return function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> | undefined {\n if (count > n) {\n return func.apply(this, args);\n }\n count += 1;\n };\n}","import { toDecorator } from '@decorator/toDecorator.js';\nimport { minCalls } from '@function/minCalls.js';\n\n/** \n * Only invokes the decorated function after it's called more than `n` times.\n * \n * Look at {@link minCalls} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * @example\n * ```typescript\n * class TestClass {\n * @decMinCalls(2)\n * testMethod() {\n * return 1;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(); // => undefined\n * instance.testMethod(); // => undefined\n * instance.testMethod(); // => 1\n * ```\n * @param n The number of calls before the decorated function is invoked.\n */\n\nexport function decMinCalls(n: number) {\n return toDecorator(minCalls)(n);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Generates a function that invokes the given function at most once per every `wait` milliseconds.\n * \n * This function can be used as a decorator with {@link decThrottle}.\n * @example\n * const throttled = throttle(() => console.log(\"Throttled!\"), 1000);\n * \n * throttled();\n * throttled();\n * // => \"Throttled!\" is logged once per second.\n * @param func The function to throttle.\n * @param wait The number of milliseconds to throttle invocations to.\n * @returns Returns the new throttled function.\n */\n\n\nexport function throttle<TFunc extends GenericFunction<TFunc>>(func: TFunc, wait: number): TFunc {\n let inThrottle = false;\n return function (this: unknown, ...args: Parameters<TFunc>) {\n if (!inThrottle) {\n func.apply(this, args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), wait);\n }\n } as TFunc;\n}\n \n","import { toDecorator } from '@decorator/toDecorator.js';\nimport { throttle } from '@function/throttle.js';\n\n/**\n * The decorated function is invoked at most once per every `wait` milliseconds.\n * \n * Look at {@link throttle} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decThrottle(1000)\n * testMethod() {\n * console.log(\"Throttled!\");\n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(); // => \"Throttled!\" is logged once per second.\n * instance.testMethod(); // nothing happens\n * ```\n * @param wait The number of milliseconds to wait between invocations.\n */\n\nexport function decThrottle(wait: number) {\n return toDecorator(throttle)(wait);\n}","/**\n * Invokes a function `n` times, returning an array of the results of\n * each invocation.\n * \n * @example\n * times(index => console.log(\"Run\", index), 3)\n * // => \"Run 0\" | \"Run 1\" | \"Run 2\"\n * times(Math.random, 3)\n * // => [0.123, 0.456, 0.789]\n * times(() => 0, 4)\n * // => [0, 0, 0, 0]\n * @param n The number of times to invoke `func`.\n * @param func The function invoked per iteration.\n * @returns Returns an array of results.\n */\n\nexport function times<TInput>(func: (index: number) => TInput, n: number): TInput[] {\n const result: TInput[] = [];\n for (let i = 0; i < n; i++) {\n result.push(func(i));\n }\n return result;\n}","/**\n * Calculates the sum of an array of numbers.\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * sum([1, 2, 3, 4, 5]) // => 15\n * \n * @param numbers The input array of numbers\n * @returns The sum of the input array \n */\n\nexport function sum(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n return numbers.reduce((total, current) => total + current, 0);\n}","import { sum } from '@number/sum.js';\n\n/**\n * Calculates the average of an array of numbers\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * average([1, 2, 3, 4, 5]) // => 3\n * \n * @param numbers The input array of numbers\n * @returns The average of the input array, or NaN if the input array is empty\n */\n\nexport function average(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n return sum(numbers) / numbers.length;\n}","/**\n * Calculates the median of an array of numbers\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * median([1, 2, 3, 4, 5]) // => 3\n * median([1, 2, 3, 4, 5, 6]) // => 3.5\n * \n * @param numbers The input array of numbers\n * @returns The median of the input array\n */\n\nexport function median(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n const sortedArray = [...numbers].sort((a, b) => a - b);\n const mid = Math.floor(sortedArray.length / 2);\n return sortedArray.length % 2 === 0 ? ((sortedArray[mid - 1] + sortedArray[mid]) / 2) : sortedArray[mid];\n}","/**\n * Rounds a number to the given precision.\n *\n * @example\n * round(1.23456, 2); // => 1.23\n * round(1.235, 1); // => 1.2\n * round(1234.56); // => 1234.56\n * \n * @param number The number to be rounded.\n * @param precision The number of decimal places to round to. Defaults to 2.\n * @returns The rounded number.\n */\n\nexport function round(number: number, precision = 2): number {\n const factor = Math.pow(10, precision);\n return Math.round((number + Number.EPSILON) * factor) / factor;\n}","import type { PlainObject } from '@type/PlainObject.js';\n\n/**\n * Checks if the value is a plain object.\n * \n * @example\n * isPlainObject({}) // => true\n * isPlainObject({ a: 1 }) // => true\n * isPlainObject(null) // => false\n * isPlainObject('1') // => false\n * isPlainObject([]) // => false\n * isPlainObject(new Function()) // => false\n * isPlainObject(new Date()) // => false\n * @param value The value to check\n * @returns Boolean indicating if the value is a plain object\n */\n\nexport function isPlainObject(value: unknown): value is PlainObject {\n return value?.constructor === Object;\n}","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\n/**\n * Flattens an object into a single level object.\n * \n * @example\n * const obj = { a: { b: 2, c: [{ d: 3 }, {d: 4 }] } };\n * flatKeys(obj);\n * // => { 'a.b': 2, 'a.c[0].d': 3, 'a.c[1].d': 4 }\n * \n * @param obj The object to flatten.\n * @template TObj The type of the object to flatten.\n * @returns A new object with flattened keys.\n */\n\nexport function flatKeys<TObj extends PlainObject>(obj: TObj): Record<string, unknown> {\n const flatObject: Record<string, unknown> = {};\n \n for (const [key, value] of Object.entries(obj)) {\n addToResult(key, value, flatObject);\n }\n \n return flatObject;\n}\n\nfunction addToResult(prefix: string, value: unknown, flatObject: Record<string, unknown>) {\n if (isPlainObject(value)) {\n const flatObj = flatKeys(value);\n for (const [flatKey, flatValue] of Object.entries(flatObj)) {\n flatObject[`${prefix}.${flatKey}`] = flatValue;\n }\n } else if (Array.isArray(value)) {\n for (const [index, element] of value.entries()) {\n addToResult(`${prefix}[${index}]`, element, flatObject);\n }\n\n } else {\n flatObject[prefix] = value;\n }\n}","import type { ArrayMinLength } from '@type/ArrayMinLength.js';\nimport type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\n/**\n * This function combines two or more objects into a single new object. Arrays and other types are overwritten.\n * \n * @example\n * // ---- Nested objects are merged ----\n * merge({ a: 1 }, { b: 2 }, { c: 3, d: { e: 4 } }) \n * // => { a: 1, b: 2, c: 3, d: { e: 4 } }\n *\n * // ---- Other types are overwritten ----\n * merge({ a: [1, 2] }, { a: [3, 4] })\n * // => { a: [3, 4] }\n * \n * merge({ a: 1 }, { a: \"Yes\" })\n * // => { a: \"Yes\" }\n * @param target The target object\n * @param sources The source objects\n * @template TTarget The type of the target object\n * @template TSources The type of the source objects\n * @returns A new merged object\n */\n\nexport function merge<TTarget extends PlainObject, TSources extends ArrayMinLength<PlainObject, 1>>(target: TTarget, ...sources: TSources): MergeDeepObjects<[TTarget, ...TSources]> {\n const targetCopy = { ...target };\n for (const source of sources) {\n for (const [key, value] of Object.entries(source)) {\n (targetCopy as PlainObject)[key] = isPlainObject(value) && isPlainObject(targetCopy[key]) \n ? merge(targetCopy[key] as PlainObject, value) \n : value;\n }\n }\n return targetCopy as MergeDeepObjects<[TTarget, ...TSources]>; \n}\n\ntype OptionalPropertyNames<T> =\n { [K in keyof T]-?: (PlainObject extends { [P in K]: T[K] } ? K : never) }[keyof T];\n\ntype SpreadProperties<L, R, K extends keyof L & keyof R> =\n { [P in K]: L[P] | Exclude<R[P], undefined> };\n\ntype Id<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;\n\ntype SpreadTwo<L, R> = Id<\n& Pick<L, Exclude<keyof L, keyof R>>\n& Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>>\n& Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>>\n& SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>\n>;\n\ntype MergeDeepObjects<A extends readonly [...unknown[]]> = A extends [infer L, ...infer R] ?\n SpreadTwo<L, MergeDeepObjects<R>> : unknown;\n","import type { PlainObject } from '@type/PlainObject.js';\n\n/**\n * Creates an object composed of the picked `object` properties.\n *\n * @example\n * const object = { 'a': 1, 'b': '2', 'c': 3 }\n *\n * pick(object, ['a', 'c'])\n * // => { 'a': 1, 'c': 3 }\n * @param object The source object.\n * @param keysToPick The property paths to pick.\n * @template TObj The type of the object.\n * @returns Returns the new object.\n */\n\nexport function pick<TObj extends PlainObject, Key extends keyof TObj>(object: TObj, keysToPick: Key[]): Pick<TObj, Key> {\n const result = {} as Pick<TObj, Key>;\n for (const key of keysToPick) {\n result[key] = object[key];\n }\n return result;\n}\n","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { pick } from './pick.js';\n\n/**\n * Omit specified keys from an object\n *\n * @example\n * const obj = {a: 1, b: 2, c: 3};\n * omit(obj, ['a', 'b']);\n * // => {c: 3}\n *\n * @param object The object to filter\n * @param keysToOmit The keys to exclude from the returned object\n * @template TObj The type of the object\n * @returns - An object without the specified keys\n */\n\nexport function omit<TObj extends PlainObject, Key extends keyof TObj>(object: TObj, keysToOmit: Key[]): Omit<TObj, Key> {\n const keys = Object.keys(object);\n const filteredKeys = keys.filter(key => !keysToOmit.includes(key as Key)) as Exclude<keyof TObj, Key>[];\n\n return pick(object, filteredKeys);\n}","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\nconst validPathRegex = /^(?:[^.[\\]]+(?:\\[\\d+])*(?:\\.|\\[\\d+]))+(?:[^.[\\]]+(?:\\[\\d+])*)+$/;\nconst pathSplitRegex = /\\.|(?=\\[)/g;\nconst matchBracketsRegex = /[[\\]]/g;\n\n/**\n * Sets the value at path of object. If a portion of path doesn’t exist, it’s created.\n * \n * @example\n * const obj = { a: { b: 2 } };\n * set(obj, 'a.c', 1);\n * // => { a: { b: 2, c: 1 } }\n * \n * // `[number]` can be used to access array elements\n * set(obj, 'a.c[0]', 'hello');\n * // => { a: { b: 2, c: ['hello'] } }\n * \n * // numbers with dots are treated as keys\n * set(obj, 'a.c.0.d', 'world');\n * // => { a: { b: 2, c: { 0: { d: 'world' } } }\n * \n * // supports numbers in keys\n * set(obj, 'a.e0.a', 1);\n * // => { a: { e0: { a: 1 } } }\n * \n * @param obj The object to modify.\n * @param path The path of the property to set.\n * @param value The value to set.\n * @template TObj The type of the object.\n * @returns The modified object.\n */\n\nexport function set(obj: PlainObject, path: string, value: unknown): PlainObject {\n if (!validPathRegex.test(path))\n throw new Error('Invalid path, look at the examples for the correct format.');\n\n const pathParts = path.split(pathSplitRegex);\n let currentObj: PlainObject = obj;\n for (let index = 0; index < pathParts.length; index++) {\n const key = pathParts[index].replace(matchBracketsRegex, '');\n\n if (index === pathParts.length - 1) {\n currentObj[key] = value;\n break;\n }\n\n const nextElemIn = pathParts[index + 1].startsWith('[') ? 'array' : 'object';\n if (currentObj[key] === undefined) {\n currentObj[key] = nextElemIn === 'array' ? [] : {};\n } else if (nextElemIn === 'array' && !Array.isArray(currentObj[key])) {\n currentObj[key] = [];\n } else if (nextElemIn === 'object' && !isPlainObject(currentObj[key])) {\n currentObj[key] = {};\n }\n currentObj = currentObj[key] as PlainObject;\n }\n\n return obj;\n}","/**\n * A class for managing a queue of async functions that runs a set number concurrently. \n * If for example you have 10 async functions and you want to run 3 at a time, you can use this class.\n * \n * If the queue is paused, the queue will not run any more async functions until it is resumed.\n * \n * **Methods:**\n * - `add` - adds a async function or array of functions to the queue. Returns a promise that resolves when the added function(s) finish.\n * - `clear` - clears the queue.\n * - `pause` - pauses the queue.\n * - `resume` - resumes the queue. \n * - `getQueue` - returns the current queue.\n * - `isPaused` - returns whether the queue is paused.\n * \n * @example\n * // Create a queue that can run 3 tasks concurrently\n * const queue = new Queue(3);\n * \n * queue.add(() => fetch('https://example.com'));\n * \n * queue.add(async () => {\n * const response = await fetch('https://example.com');\n * return response.json();\n * });\n * \n * // Add an array of tasks to the queue and wait for them to resolve\n * await queue.add([\n * () => fetch('https://apple.com'),\n * () => fetch('https://microsoft.com')\n * ]);\n * // => [Response, Response]\n */\n\nexport class Queue {\n private running = 0;\n private maxConcurrent: number;\n private paused = false;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private queue: { asyncFn: () => Promise<any>, resolve: (value: any) => void, reject: (reason?: any) => void }[] = [];\n\n /**\n * @constructor\n * @param maxConcurrent The maximum number of async functions to run concurrently.\n */\n constructor(maxConcurrent: number) {\n this.maxConcurrent = maxConcurrent;\n }\n\n /**\n * Add aync functions or an array of async functions to the queue.\n * \n * @param asyncFn The aync function(s) to add to the queue.\n * @returns A promise that resolves when the added function(s) finishes.\n */\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn): Promise<TProm>;\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn[]): Promise<TProm[]>;\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn | TAsyncFn[]): Promise<TProm> | Promise<TProm[]> {\n if (Array.isArray(asyncFn)) {\n const promises = asyncFn.map((fn) => this.buildWaitingPromise(fn));\n return Promise.all(promises);\n } else {\n return this.buildWaitingPromise(asyncFn);\n } \n }\n\n private buildWaitingPromise<TProm>(asyncFn: () => Promise<TProm>): Promise<TProm> {\n return new Promise((resolve, reject) => {\n this.queue.push({ asyncFn, resolve, reject });\n this.run();\n });\n } \n\n private run() {\n while (this.queue.length > 0 && this.running < this.maxConcurrent && !this.paused) {\n this.running++;\n const queueElement = this.queue.shift()!;\n void queueElement.asyncFn()\n .then((result) => {\n queueElement.resolve(result);\n }).catch((error) => {\n queueElement.reject(error);\n }).finally(() => {\n this.running--;\n this.run();\n });\n }\n }\n\n /** Removes all the tasks from the queue */\n clear() {\n for (const queueElement of this.queue) {\n queueElement.reject(new Error('Queue cleared'));\n }\n this.queue = [];\n }\n\n /** Pauses the execution of the queue */\n pause() {\n this.paused = true;\n }\n\n /** Resumes the execution of the tasks in the queue */\n resume() {\n this.paused = false;\n this.run();\n }\n\n /** Return the tasks added to the queue */\n getQueue() {\n return this.queue.map((queueElement) => queueElement.asyncFn);\n }\n\n /** Returns whether the queue is paused */\n isPaused() {\n return this.paused;\n }\n\n}\n","/**\n * Similar to [Promise.race](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race?retiredLocale=de) \n * but allows to specify how many promises to wait for.\n *\n * @example\n * const prom1 = Promise.resolve(1);\n * const prom2 = new Promise(resolve => setTimeout(resolve, 100, 2));\n * const prom3 = Promise.resolve(3);\n * \n * const firstTwo = await races(2, prom1, prom2, prom3);\n * // => [1, 3]\n * \n * @template TRes The type of the result of the promises.\n * @param waitFor The number of promises to wait for.\n * @param promises The promises to wait for.\n * @returns A promise that resolves an array of the results of the first n promises.\n */\n\nexport function races<TRes>(waitFor: number, ...promises: Promise<TRes>[]): Promise<TRes[]> {\n return new Promise((resolve, reject) => {\n if (promises.length < waitFor)\n waitFor = promises.length;\n\n const results: TRes[] = [];\n let resolved = 0;\n for (const promise of promises) {\n promise.then((value) => {\n results.push(value);\n resolved++;\n if (resolved >= waitFor) {\n resolve(results);\n }\n }).catch((error) => {\n reject(error);\n });\n }\n });\n}","/**\n * Sleeps for the given amount of time.\n *\n * @example\n * await sleep(1000);\n * // => Waits for 1 second.\n * @param ms Amount of time to sleep in milliseconds.\n * @returns A promise that resolves after the given amount of time.\n */\nexport function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}","/* eslint-disable no-await-in-loop */\nimport { sleep } from '@promise/sleep.js';\n\n/**\n * Retry a function until it succeeds or the maximum number of retries is reached.\n * \n * Default maxRetries: `5`. \n * Default backoff: `2^retries * 100ms` (100, 200, 400, 800, 1600, 3200, ...)\n *\n * @example\n * await retry(() => fetch('https://example.com'));\n * \n * // ---- Advanced example ----\n * const fetchSite = async () => {\n * const response = await fetch('https://example.com');\n * if(!response.ok)\n * throw new Error('Failed to fetch');\n * }\n * \n * const logger = (error: unknown, retry?: number) => console.log(\"Retrying\", retry, error);\n * \n * await retry(fetchSite, { maxRetries: 3, backoff: retries => retries * 1000, onRetry: logger });\n * // => Will retry 3 times with a 1 second delay between each retry.\n * // => Will log the error and retry number.\n * \n * @param func The function to retry.\n * @param options The options for the retry.\n * @param options.maxRetries The maximum number of retries. Defaults to `5`.\n * @param options.backoff The backoff function to use. Defaults to `2^retries * 100`.\n * @param options.onRetry The function to call when a retry is attempted. It will be called with the error and the attempt number.\n * @template TRes The type of the result of the function.\n * @returns A promise that resolves when the function succeeds.\n */\n\nexport async function retry<TRes>(\n func: () => Promise<TRes>, \n options?: { \n maxRetries?: number,\n backoff?: ((retries: number) => number),\n onRetry?: (error?: unknown, attempted?: number) => void\n }\n): Promise<TRes> {\n const backOffFn = options?.backoff ?? (retries => (2 ** retries) * 100);\n const maxRetries = options?.maxRetries ?? 5;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n const onRetry = options?.onRetry ?? (() => {});\n let retries = 0;\n let lastError: unknown;\n\n while (retries <= maxRetries) {\n try {\n if (retries > 0)\n onRetry(lastError, retries);\n return await func();\n } catch (error) {\n lastError = error;\n retries++;\n if (retries > maxRetries) {\n throw error;\n }\n await sleep(backOffFn(retries));\n }\n /* c8 ignore next 2 */\n }\n throw new Error('Retry terminated without success, this should never happen');\n}","/**\n * Returns a new promise that will reject with an error after a specified timeout. \n *\n * @example\n * try {\n * await timeout(fetch('https://example.com'), 1000);\n * } catch (error) {\n * console.log(error.message);\n * // => 'Promise timed out after 1000ms'\n * }\n * @template TRes - The type of the resolved value.\n * @param promise The promise to wrap.\n * @param timeout The timeout in milliseconds.\n * \n * @returns A new promise that will reject with an error after the specified timeout.\n */\nexport function timeout<TRes>(promise: Promise<TRes>, timeout: number): Promise<TRes> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error(`Promise timed out after ${timeout}ms`));\n }, timeout);\n \n promise.then(\n (result) => {\n clearTimeout(timeoutId);\n resolve(result);\n },\n (error) => {\n clearTimeout(timeoutId);\n reject(error);\n }\n );\n });\n}","/**\n * Attempts to execute a promise and returns an array with the result or error.\n * \n * This is useful for handling errors in async functions without try/catch blocks.\n * \n * @example\n * ```typescript\n * const [data, error] = await tryCatch(fetch('https://example.com/api'));\n * if (error)\n * console.error(`Error: ${error.message}`);\n * ```\n * @param promise A Promise to be executed.\n * @returns A Promise that resolves to an array containing the result or error. \n * If the Promise executes successfully, the array contains the result and a null error. \n * If the Promise throws an error, the array contains undefined for the result and the error object.\n *\n * @template TRes The type of the result.\n */\n\nexport async function tryCatch<TRes>(promise: Promise<TRes>): Promise<[TRes, undefined] | [undefined, Error]> {\n try {\n const data = await promise;\n return [data, undefined];\n } catch (error) {\n if (error instanceof Error)\n return [undefined, error];\n\n throw error;\n }\n}","// Split non-alphanumeric characters with spaces and deal with camel/PascalCase\nconst splitWordsRegex = new RegExp(\n '[^\\\\dA-Za-z]' + // match any character that is not a letter or a digit\n '|' + // or\n '(?<=[a-z])' + // lookbehind for a lowercase letter\n '(?=[A-Z])' + // lookahead for an uppercase letter\n '|' + // or\n '(?<=[A-Z])' + // lookbehind for an uppercase letter\n '(?=[A-Z][a-z])' // lookahead for an uppercase letter followed by a lowercase letter\n);\n\n/**\n * Split a string into words. Can deal with camelCase, PascalCase & snake_case.\n * \n * @example\n * splitWords('camelCase')\n * // => ['camel', 'Case']\n * \n * splitWords('PascalCase')\n * // => ['Pascal', 'Case']\n * \n * splitWords('hello_world-123')\n * // => ['hello', 'world', '123']\n * \n * @param str The string to split into words.\n * @returns An array of words.\n */\n\nexport function splitWords(str: string): string[] {\n return str.split(splitWordsRegex).filter(Boolean);\n}","const accentControlRegex = /[\\u0300-\\u036F]/g;\n\n/**\n * Deburrs a string by converting\n * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n * letters to basic Latin letters and removing\n * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n *\n * @example\n * deburr('déjà vu')\n * // => 'deja vu'\n * @param str The string to deburr.\n * @returns Returns the deburred string.\n */\n\nexport function deburr(str: string): string {\n return str.normalize('NFD').replace(accentControlRegex, '');\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts `string` to camelCase.\n *\n * @example\n * camelCase('Foo Bar')\n * // => 'fooBar'\n * camelCase('--foo-bar--')\n * // => 'fooBar'\n * camelCase('__FOO_BAR__')\n * // => 'fooBar'\n * @param str The string to convert.\n * @returns Returns the camel cased string.\n */\n\nexport function camelCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n\n // Capitalize the first letter of each word\n const camelCase = words.map((word: string, index: number) => {\n if (index === 0) {\n return word.toLowerCase();\n }\n return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n });\n\n return camelCase.join('');\n}\n","/**\n * Converts the first character of a string to upper case and the remaining to lower case.\n *\n * @example\n * capitalize('FRED')\n * // => 'Fred'\n * @param str The string to capitalize.\n * @returns Returns the capitalized string.\n */\n\nexport function capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","const charRegex = /[\"&'<>]/g;\nconst escapeChars = new Map([\n ['&', '&amp;'],\n ['<', '&lt;'],\n ['>', '&gt;'],\n ['\\'', '&#39;'],\n ['\"', '&quot;']\n]);\n\n/**\n * Converts the characters `&`, `<`, `>`, `\"` and `'` in a string to their corresponding HTML entities.\n *\n * @example\n * escapeHtml('fred, barney, & pebbles')\n * // => 'fred, barney, &amp; pebbles'\n * @param str The string to escape.\n * @returns Returns the escaped string.\n */\n\nexport function escapeHtml(str: string): string {\n return str.replace(charRegex, char => escapeChars.get(char)!);\n}\n","const escapleCharsRegex = /[$()*+.?[\\\\\\]^{|}]/g;\n\n/**\n * Escapes the `RegExp` special characters `^`, `$`, `\\`, `.`, `*`, `+`,\n * `?`, `(`, `)`, `[`, `]`, `{`, `}`, and `|` in a string.\n *\n * @example\n * escapeRegExp('[moderndash](https://moderndash.io/)')\n * // => '\\[moderndash\\]\\(https://moderndash\\.io/\\)'\n * @param str The string to escape.\n * @returns Returns the escaped string.\n */\n\nexport function escapeRegExp(str: string): string {\n return str.replace(escapleCharsRegex, '\\\\$&');\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to kebab-case.\n *\n * @example\n * kebabCase('Foo Bar')\n * // => 'foo-bar'\n * kebabCase('fooBar')\n * // => 'foo-bar'\n * kebabCase('__FOO_BAR__')\n * // => 'foo-bar'\n * \n * @param str The string to convert.\n * @returns Returns the kebab cased string.\n */\n\nexport function kebabCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let kebabCase = '';\n for (const word of words) {\n kebabCase += word.toLowerCase() + '-';\n }\n return kebabCase.slice(0, -1);\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n\n/**\n * Converts a string to PascalCase.\n *\n * @example\n * pascalCase('Foo Bar')\n * // => 'FooBar'\n * pascalCase('fooBar')\n * // => 'FooBar'\n * pascalCase('__FOO_BAR__')\n * // => 'FooBar'\n * \n * @param str The string to convert.\n * @returns Returns the pascal cased string.\n */\n\nexport function pascalCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let pascalCase = '';\n for (const word of words) {\n pascalCase += word.charAt(0).toUpperCase() + word.slice(1);\n }\n return pascalCase;\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to snake_case.\n *\n * @example\n * snakeCase('Foo Bar')\n * // => 'foo_bar'\n * snakeCase('fooBar')\n * // => 'foo_bar'\n * snakeCase('--FOO-BAR--')\n * // => 'foo_bar'\n * snakeCase('foo2bar')\n * // => 'foo_2_bar'\n * \n * @param str The string to convert.\n * @returns Returns the snake cased string.\n */\n\nexport function snakeCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let snakeCase = '';\n for (const word of words) {\n if (snakeCase.length > 0) {\n snakeCase += '_';\n }\n snakeCase += word.toLowerCase();\n }\n return snakeCase;\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to Title Case.\n *\n * @example\n * titleCase('--foo-bar--')\n * // => 'Foo Bar'\n * titleCase('fooBar')\n * // => 'Foo Bar'\n * titleCase('__FOO_BAR__')\n * // => 'Foo Bar'\n * titleCase('HélloWorld')\n * // => 'Hello World'\n * @param str The string to convert.\n * @returns Returns the title cased string.\n */\n\nexport function titleCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let titleCase = '';\n for (const word of words) {\n titleCase += word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() + ' ';\n }\n return titleCase.trimEnd();\n}\n","const htmlEntitiesRegex = /&(?:amp|lt|gt|quot|#39);/g;\nconst entityMap = new Map([\n ['&amp;', '&'],\n ['&lt;', '<'],\n ['&gt;', '>'],\n ['&quot;', '\"'],\n ['&#39;', '\\'']\n]);\n\n/**\n * Converts the HTML entities `&amp;`, `&lt;`, `&gt;`, `&quot;` and `&#39;`\n * in a string to their corresponding characters.\n *\n * @example\n * unescapeHtml('fred, barney, &amp; pebbles')\n * // => 'fred, barney, & pebbles'\n * @param str The string to unescape.\n * @returns Returns the unescaped string.\n */\n\nexport function unescapeHtml(str: string): string {\n return str.replace(htmlEntitiesRegex, (entity: string) => entityMap.get(entity)!);\n}\n","/**\n * Checks if `value` is an empty object, collection, map, or set.\n *\n * @example\n * isEmpty(null)\n * // => true\n *\n * isEmpty({})\n * // => true\n *\n * isEmpty(\"\")\n * // => true\n *\n * isEmpty([1, 2, 3])\n * // => false\n *\n * isEmpty('abc')\n * // => false\n *\n * isEmpty({ 'a': 1 })\n * // => false\n * @param value The value to check.\n * @returns Returns `true` if given vlaue is empty, else `false`.\n */\n\nexport function isEmpty(value: string | object | null | undefined): boolean {\n if (value === null || value === undefined) {\n return true;\n }\n\n if (typeof value === 'string' || Array.isArray(value)) {\n return value.length === 0;\n }\n\n if (value instanceof Map || value instanceof Set) {\n return value.size === 0;\n }\n\n if (typeof value === 'object') {\n return Object.keys(value).length === 0;\n }\n\n return false;\n}\n","/* eslint-disable complexity */\nimport type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from './isPlainObject.js';\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * @example\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n * @param a The value to compare.\n * @param b The other value to compare.\n * @returns Returns `true` if the values are equivalent, else `false`.\n */\n\nexport function isEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n \n if (typeof a !== typeof b) return false;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return isSameArray(a, b);\n }\n\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.toString() === b.toString();\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n return isSameObject(a, b);\n }\n\n return false;\n}\n\nfunction isSameObject(a: PlainObject, b: PlainObject) {\n // check if the objects have the same keys\n const keys1 = Object.keys(a);\n const keys2 = Object.keys(b);\n if (!isEqual(keys1, keys2)) return false;\n\n // check if the values of each key in the objects are equal\n for (const key of keys1) {\n if (!isEqual(a[key], b[key])) return false;\n }\n\n // the objects are deeply equal\n return true;\n}\n\nfunction isSameArray(a: unknown[], b: unknown[]) {\n if (a.length !== b.length) return false;\n\n // check if the values of each element in the arrays are equal\n for (const [i, element] of a.entries()) {\n if (!isEqual(element, b[i])) return false;\n }\n\n return true;\n}\n","/**\n * Checks if given string is a valid URL\n *\n * @example\n * isUrl('https://google.com')\n * // => true\n * isUrl('google.com')\n * // => false\n * @param str The string to check.\n * @returns Returns `true` if given string is a valid URL, else `false`.\n */\n\nexport function isUrl(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return false;\n }\n}"],"mappings":"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","names":["difference","intersection","range","range","randomFloat","count","count","retries","timeout","camelCase","kebabCase","pascalCase","snakeCase","titleCase"]}
1
+ {"version":3,"sources":["../src/array/chunk.ts","../src/array/count.ts","../src/helpers/fastArrayFlat.ts","../src/array/difference.ts","../src/array/dropRightWhile.ts","../src/array/dropWhile.ts","../src/array/group.ts","../src/array/unique.ts","../src/array/intersection.ts","../src/array/range.ts","../src/array/shuffle.ts","../src/array/sort.ts","../src/array/takeRightWhile.ts","../src/array/takeWhile.ts","../src/crypto/hash.ts","../src/crypto/randomInt.ts","../src/crypto/randomElem.ts","../src/crypto/randomFloat.ts","../src/crypto/randomString.ts","../src/decorator/toDecorator.ts","../src/function/debounce.ts","../src/decorator/decDebounce.ts","../src/function/maxCalls.ts","../src/decorator/decMaxCalls.ts","../src/function/memoize.ts","../src/decorator/decMemoize.ts","../src/function/minCalls.ts","../src/decorator/decMinCalls.ts","../src/function/throttle.ts","../src/decorator/decThrottle.ts","../src/function/times.ts","../src/number/sum.ts","../src/number/average.ts","../src/number/median.ts","../src/number/round.ts","../src/validate/isPlainObject.ts","../src/object/flatKeys.ts","../src/object/merge.ts","../src/object/pick.ts","../src/object/omit.ts","../src/object/set.ts","../src/promise/queue.ts","../src/promise/races.ts","../src/promise/sleep.ts","../src/promise/retry.ts","../src/promise/timeout.ts","../src/promise/tryCatch.ts","../src/string/splitWords.ts","../src/string/deburr.ts","../src/string/camelCase.ts","../src/string/capitalize.ts","../src/string/escapeHtml.ts","../src/string/escapeRegExp.ts","../src/string/kebabCase.ts","../src/string/pascalCase.ts","../src/string/snakeCase.ts","../src/string/titleCase.ts","../src/string/unescapeHtml.ts","../src/validate/isEmpty.ts","../src/validate/isEqual.ts","../src/validate/isUrl.ts"],"sourcesContent":["/**\n * Creates an array of elements split into groups the length of size. If array can't be split evenly, the final chunk will be the remaining elements.\n *\n * @example\n * chunk(['a', 'b', 'c', 'd'], 2)\n * // => [['a', 'b'], ['c', 'd']]\n *\n * chunk(['a', 'b', 'c', 'd'], 3)\n * // => [['a', 'b', 'c'], ['d']]\n * @param chunkSize The length of each chunk\n * @param array The array to chunk.\n * @template TElem The type of the array elements.\n * @returns Returns the new array of chunks.\n */\n\nexport function chunk<TElem>(array: readonly TElem[], chunkSize: number): TElem[][] {\n const intSize = Math.trunc(chunkSize);\n if (array.length === 0 || intSize < 1) {\n return [];\n }\n \n let index = 0;\n let resultIndex = 0;\n const result = new Array(Math.ceil(array.length / intSize)) as TElem[][];\n\n while (index < array.length) {\n result[resultIndex++] = array.slice(index, (index += intSize));\n }\n\n return result;\n}\n","/**\n * Creates an object with counts of occurrences of items in the array.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true, age: 36 },\n * { 'user': 'betty', 'active': false, age: 36 },\n * { 'user': 'fred', 'active': true, age: 40 }\n * ]\n *\n * count(users, value => value.active ? 'active' : 'inactive');\n * // => { 'active': 2, 'inactive': 1 }\n *\n * count(users, value => value.age);\n * // => { 36: 2, 40: 1 }\n *\n * @param criteria The criteria to count by.\n * @param array The array or record to iterate over.\n * @template TElem The type of the array elements.\n * @returns Returns the composed aggregate object.\n */\n\nexport function count<TElem, TKey extends PropertyKey>(array: readonly TElem[], criteria: (value: TElem) => TKey): Record<TKey, number> {\n const result = {} as Record<TKey, number>;\n for (const value of array) {\n const key = criteria(value);\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n result[key] = (result[key] ?? 0) + 1;\n }\n return result;\n}","// native array.flat is much slower than this - node 19\nexport function fastArrayFlat<TElem>(arrays: (readonly TElem[])[]): readonly TElem[] {\n let result = arrays.shift() ?? [];\n\n for (const array of arrays) {\n result = [...result, ...array];\n }\n\n return result;\n}","import type { CompareFunction } from '@helpers/ArrayTypeUtils.js';\nimport type { ArrayMinLength } from '@type/ArrayMinLength.js';\n\nimport { fastArrayFlat } from '@helpers/fastArrayFlat.js';\n\n/**\n * Create a new array with values from the first array that are not present in the other arrays.\n * \n * Optionally, use a compare function to determine the comparison of elements (default is `===`).\n * \n * @example\n * difference([2, 1], [2, 3], [6])\n * // => [1]\n *\n * // ---- Custom compare function ----\n * const compareByFloor = (a, b) => Math.floor(a) === Math.floor(b);\n * difference([1.2, 3.1], [1.3, 2.4], compareByFloor)\n * // => [3.1]\n *\n * // ---- Only compare by id ----\n * const arr1 = [{ id: 1, name: 'Yeet' }, { id: 3, name: 'John' }];\n * const arr2 = [{ id: 3, name: 'Carl' }, { id: 4, name: 'Max' }];\n *\n * difference(arr1, arr2, (a, b) => a.id === b.id)\n * // => [{ id: 1, name: 'Yeet' }]\n * @param arraysOrCompareFn Two or more arrays with an optional compare function at the end.\n * @template TElem The type of the array elements.\n * @template TArrays The type of the arrays provided.\n * @returns Returns the new array of filtered values.\n */\n\nexport function difference<TElem>(...arraysOrCompareFn: ArrayMinLength<TElem[], 2>): TElem[];\nexport function difference<TArrays extends ArrayMinLength<unknown[], 2>>(...arraysOrCompareFn: [...TArrays, CompareFunction<TArrays>]): TArrays[0];\nexport function difference<TArrays extends ArrayMinLength<unknown[], 2>, TElem>(...arraysOrCompareFn: ArrayMinLength<TElem[], 2> | [...TArrays, CompareFunction<TArrays>]): TArrays[0] {\n const compareFnProvided = typeof arraysOrCompareFn.at(-1) === 'function';\n const compareFunction = compareFnProvided && arraysOrCompareFn.pop() as CompareFunction<TArrays>;\n\n const arrays = arraysOrCompareFn as TArrays;\n const firstArray = arrays.shift()!;\n const combinedRestArray = fastArrayFlat(arrays);\n\n if (!compareFunction) {\n const restSet = new Set(combinedRestArray);\n return firstArray.filter(element => !restSet.has(element));\n }\n\n const difference: TArrays[0] = [];\n for (const element of firstArray) {\n if (combinedRestArray.every(item => !compareFunction(element, item))) {\n difference.push(element);\n }\n }\n\n return difference;\n}","/**\n * Creates a slice of `array` excluding elements dropped from the end. \n * Elements are dropped until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': true }\n * ]\n *\n * dropRightWhile(users, user => user.active)\n * // => objects for ['barney']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function dropRightWhile<TElem>(array: readonly TElem[], predicate: (value: TElem) => boolean) {\n let i = array.length;\n while (i > 0 && predicate(array[i - 1])) {\n i--;\n }\n return array.slice(0, i);\n}\n","/**\n * Creates a slice of `array` excluding elements dropped from the beginning. \n * Elements are dropped until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': false }\n * ]\n *\n * dropWhile(users, user => user.active)\n * // => objects for ['pebbles']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function dropWhile<TElem>(array: readonly TElem[], predicate: (value: TElem) => boolean): TElem[] {\n const index = array.findIndex(x => !predicate(x));\n return array.slice(index === -1 ? array.length : index);\n}\n","/**\n * Creates an object with grouped items in the array.\n *\n * @example\n * group([6.1, 4.2, 6.3], Math.floor)\n * // => { 4: [4.2], 6: [6.1, 6.3] }\n *\n * group([6.1, 4.2, 6.3], value => value > 5 ? '>5' : '<=5')\n * // => { '<=5': [4.2], '>5': [6.1, 6.3] }\n * \n * @param collection The array or object to iterate over.\n * @param getGroupKey A function that returns the group id for each item.\n * @template TElem The type of the array elements.\n * @returns An object with grouped items.\n */\n\nexport function group<TElem, TKey extends PropertyKey>(array: readonly TElem[], getGroupKey: (elem: TElem) => TKey): Record<TKey, TElem[]> {\n const result = {} as Record<TKey, TElem[]>;\n for (const elem of array) {\n const key = getGroupKey(elem);\n (result[key] ??= []).push(elem);\n }\n return result;\n}","/**\n * Creates a duplicate-free version of an array, in which only the first occurrence of each element is kept. \n * The order of result values is determined by the order they occur in the array.\n *\n * A compare function is optional to specify how the array is compared (default is `===`).\n * \n * @example\n * unique([2, 1, 2])\n * // => [2, 1]\n * \n * // compare by object values\n * const users = [\n * { id: 1, name: 'john' },\n * { id: 2, name: 'john' },\n * { id: 2, name: 'john' },\n * ]\n * \n * unique(users, isEqual)\n * // => [{ id: 1, name: 'john' }, { id: 2, name: 'john' }]\n * \n * // compare by id\n * unique(users, (a, b) => a.name === b.name)\n * // => [{ id: 1, name: 'john' }]\n *\n * @param array The array to inspect.\n * @param iteratee The iteratee invoked per element.\n * @template TElem The type of the array elements.\n * @returns Returns the new duplicate free array.\n */\n\nexport function unique<TElem>(array: readonly TElem[], compareFn?: (a: TElem, b: TElem) => boolean): TElem[] {\n // Arrays optimized with native Set\n if (!compareFn)\n return [...new Set(array)];\n\n const uniqueArray: TElem[] = [];\n for (const value of array) {\n let isUnique = true;\n \n for (const uniqueValue of uniqueArray) {\n if (compareFn(value, uniqueValue)) {\n isUnique = false;\n break;\n }\n }\n \n if (isUnique)\n uniqueArray.push(value);\n }\n \n return uniqueArray;\n}\n","import type { CompareFunction } from '@helpers/ArrayTypeUtils.js';\nimport type { ArrayMinLength } from '@type/ArrayMinLength.js';\n\nimport { fastArrayFlat } from '@helpers/fastArrayFlat.js';\n\nimport { unique } from './unique.js';\n\n/**\n * Create an array with unique values that are present in all arrays. \n * The order of the values is based on the first array. \n * \n * Optionally, use a compare function for element comparison (default is `===`).\n * @example\n * intersection([2, 1], [2, 3], [6, 2])\n * // => [2]\n *\n * // ---- Custom compare function ----\n * const compareFn = (a, b) => Math.floor(a) === Math.floor(b);\n * \n * intersection([1.2, 1.1], [1.3, 2.4], compareFn)\n * // => [1.2]\n *\n * // ---- Only compare by id ----\n * const arr1 = [{ id: 1, name: 'Yeet' }, { id: 3, name: 'John' }];\n * const arr2 = [{ id: 3, name: 'Carl' }, { id: 4, name: 'Max' }];\n *\n * intersection(arr1, arr2, (a, b) => a.id === b.id)\n * // => [{ id: 3, name: 'John' }]\n * @param arraysOrCompareFn Two or more arrays with an optional compare function at the end.\n * @template TElem The type of the array elements.\n * @template TArrays The type of the arrays provided.\n * @returns Returns the new array of intersecting values.\n */\n\nexport function intersection<TElem>(...arraysOrCompareFn: ArrayMinLength<TElem[], 2>): TElem[];\nexport function intersection<TArrays extends ArrayMinLength<unknown[], 2>>(...arraysOrCompareFn: [...TArrays, CompareFunction<TArrays>]): TArrays[0];\nexport function intersection<TArrays extends ArrayMinLength<unknown[], 2>, TElem>(...arraysOrCompareFn: ArrayMinLength<TElem[], 2> | [...TArrays, CompareFunction<TArrays>]): TArrays[0] {\n const compareFnProvided = typeof arraysOrCompareFn.at(-1) === 'function';\n const compareFunction = compareFnProvided && arraysOrCompareFn.pop() as CompareFunction<TArrays>;\n\n const arrays = arraysOrCompareFn as TArrays;\n const firstArray = unique(arrays.shift()!);\n const combinedRestArray = fastArrayFlat(arrays);\n\n if (!compareFunction) {\n const restSet = new Set(combinedRestArray);\n return firstArray.filter(element => restSet.has(element));\n }\n \n const intersection: TArrays[0] = [];\n\n for (const element of firstArray) {\n if (combinedRestArray.some(item => compareFunction(element, item))) {\n intersection.push(element);\n }\n }\n\n return intersection;\n}\n","/**\n * Generates an iterable sequence of numbers starting from `start`, up to and including `end`,\n * with a given `step` between each number.\n *\n * @example\n * for (const num of range(1, 5)) {\n * console.log(num);\n * }\n * // => 1 2 3 4 5\n * \n * // Generate an array of even numbers between 0 and 10:\n * const arr = [...range(0, 10, 2)];\n * // => [0, 2, 4, 6, 8, 10]\n * \n * @param start The starting number of the sequence.\n * @param end The end number of the sequence.\n * @param step The step between each number in the sequence. Defaults to 1.\n *\n * @returns An iterable sequence of numbers between `start` and `end`, inclusive, with increments of `step`.\n */\nexport function* range(start: number, end: number, step = 1): Generator<number> {\n if (start > end)\n throw new Error('The start of the range must be less than or equal to the end.');\n\n if (step <= 0)\n throw new Error('The step must be greater than 0.');\n \n for (let i = start; i <= end; i += step) {\n yield i;\n }\n}","/**\n * Creates a new array of shuffled values, using the Fisher-Yates-Durstenfeld Shuffle algorithm.\n *\n * @example\n * shuffle([1, 2, 3, 4])\n * // => [4, 1, 3, 2]\n * @param array The array or object to shuffle.\n * @template TElem The type of the array elements.\n * @returns Returns a new shuffled array.\n */\n\nexport function shuffle<TElem>(array: readonly TElem[]): TElem[] {\n const shuffledArray = [...array];\n \n for (let index = shuffledArray.length - 1; index > 0; index--) {\n const randomIndex = Math.floor(Math.random() * (index + 1));\n [shuffledArray[index], shuffledArray[randomIndex]] = [shuffledArray[randomIndex], shuffledArray[index]];\n }\n \n return shuffledArray;\n}","\n/**\n * Creates a new sorted array in ascending or descending order based on one or multiple sorting criteria.\n * \n * @example\n * sort([1, 2, 3, 4], { order: 'desc' })\n * // => [4, 3, 2, 1]\n * \n * // --- Sorting by multiple properties ---\n * const array = [{ a: 2, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 1 }];\n * \n * sort(array,\n * { order: 'asc', by: item => item.a },\n * { order: 'desc', by: item => item.b }\n * )\n * // => [{ a: 1, b: 2 }, { a: 1, b: 1 }, { a: 2, b: 1 }]\n * @param array The array to sort.\n * @param orders The sorting criteria, one or multiple objects with properties order (either 'asc' or 'desc') and by (iteratee function to sort based on a specific property).\n * @param orders.order - The order to sort in, either 'asc' or 'desc'.\n * @param orders.by - The iteratee function to sort based on a specific property.\n * @template TElem The type of the array elements.\n * @returns Returns a new sorted array.\n*/\nexport function sort<TElem>(array: readonly TElem[], ...orders: { order?: 'asc' | 'desc', by?: (item: TElem) => number | bigint | Date | string }[]): TElem[] {\n return [...array].sort((a, b) => {\n for (const { order, by } of orders) {\n const aValue = by ? by(a) : a;\n const bValue = by ? by(b) : b;\n if (aValue < bValue) {\n return order === 'desc' ? 1 : -1; \n }\n if (aValue > bValue) {\n return order === 'desc' ? -1 : 1;\n }\n }\n return 0;\n });\n}","/**\n * Creates a slice of `array` with elements taken from the end. \n * Elements are taken until `predicate` returns falsey.\n * \n * @example\n * const users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': true }\n * ]\n *\n * takeRightWhile(users, user => user.active)\n * // => objects for ['fred', 'pebbles']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function takeRightWhile<TElem>(array: readonly TElem[], predicate: (elem: TElem) => boolean): TElem[] {\n const result: TElem[] = [];\n\n for (let i = array.length - 1; i >= 0; i--) {\n if (predicate(array[i])) {\n result.unshift(array[i]);\n } else {\n break;\n }\n }\n\n return result;\n}\n","/**\n * Creates a slice of `array` with elements taken from the beginning. \n * Elements are taken until `predicate` returns falsey.\n *\n * @example\n * const users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': true },\n * { 'user': 'pebbles', 'active': false }\n * ]\n *\n * takeWhile(users, user => user.active)\n * // => objects for ['barney', 'fred']\n * @param predicate The function invoked per iteration.\n * @param array The array to query.\n * @template TElem The type of the array elements.\n * @returns Returns the slice of `array`.\n */\n\nexport function takeWhile<TElem>(array: readonly TElem[], predicate: (elem: TElem) => boolean): TElem[] {\n const result: TElem[] = [];\n\n for (const element of array) {\n if (predicate(element)) {\n result.push(element);\n } else {\n break;\n }\n }\n\n return result;\n}\n","import type { Jsonifiable } from '@type/Jsonifiable.js';\n\ntype SupportedAlgorithms = 'SHA-256' | 'SHA-384' | 'SHA-512';\n\nlet textEncoder: TextEncoder | undefined;\n\n/**\n * Generates a hash from the given data using the specified algorithm.\n *\n * It uses the Web Crypto API to generate the hash.\n * \n * *Note: If you need a secure hash use a specialized library like [crypto-js](https://www.npmjs.com/package/crypto-js) instead.*\n * \n * @example\n * // Hash a string using the default algorithm (SHA-256)\n * await hash('hello world'); \n * // => \"b94d27b9934d3e08a52e52d7da7dabfac484efe37a53...\"\n *\n * // Hash an object using the SHA-512 algorithm\n * await hash({ foo: 'bar', baz: 123 }, 'SHA-512');\n * // => \"d8f3c752c6820e580977099368083f4266b569660558...\"\n * \n * @param data The data to hash, either as a string or a JSON-serializable object.\n * @param algorithm The hashing algorithm to use. Defaults to 'SHA-256'.\n * @returns A Promise that resolves to the hexadecimal representation of the hash.\n *\n * @throws {DOMException} If the specified algorithm is not supported by the Web Crypto API.\n */\n\nexport async function hash(data: Jsonifiable, algorithm: SupportedAlgorithms = 'SHA-256'): Promise<string> {\n textEncoder ??= new TextEncoder();\n\n const dataBuffer = typeof data === 'string'\n ? textEncoder.encode(data) \n : textEncoder.encode(JSON.stringify(data));\n \n const hashBuffer = await crypto.subtle.digest(algorithm, dataBuffer);\n const hashArray = [...new Uint8Array(hashBuffer)];\n const hexValues = hashArray.map(b => b.toString(16).padStart(2, '0'));\n return hexValues.join('');\n}\n","\n/**\n * Generates a random integer between two given numbers, including those numbers.\n * \n * It uses `crypto.getRandomValues` to generate the random number.\n * @example\n * randomInt(1, 10) \n * // => 5\n * \n * @param min The smallest integer that can be generated.\n * @param max The largest integer that can be generated.\n * \n * @returns A random integer between `min` and `max`, including `min` and `max`.\n */\n\nexport function randomInt(min: number, max: number): number {\n // Taken from https://stackoverflow.com/a/41452318\n if (!Number.isInteger(min) || !Number.isInteger(max))\n throw new TypeError('min and max must be integers');\n\n if (min >= max) \n throw new Error('max must be greater than min');\n\n const range = max - min + 1;\n const randomBytes = Math.ceil(Math.log2(range) / 8);\n const maxRandNumber = Math.pow(256, randomBytes);\n const randomBuffer = new Uint8Array(randomBytes);\n\n let randomValue: number;\n do {\n crypto.getRandomValues(randomBuffer);\n randomValue = 0;\n for (let index = 0; index < randomBytes; index++) {\n // eslint-disable-next-line no-bitwise\n randomValue = (randomValue << 8) + randomBuffer[index];\n }\n // rerun if randomValue is bigger than range\n } while (randomValue >= maxRandNumber - (maxRandNumber % range));\n\n return min + (randomValue % range);\n}\n","import { randomInt } from './randomInt.js';\n\n/**\n * Gets a random element an array. A single element is returned by default. \n * Specify the `multi` parameter to get an array of multiple random elements.\n *\n * If the array is empty, `undefined` is returned. \n * If `multi` is defined it returns an empty array.\n * \n * It uses `crypto.getRandomValues` to get the random element.\n * @example\n * randomElem([1, 2, 3, 4])\n * // => 2\n *\n * randomElem([1, 2, 3, 4], 2)\n * // => [3, 1]\n * @param array The array to sample.\n * @returns Returns the random element.\n */\n\nexport function randomElem<TArr>(array: TArr[]): TArr | undefined;\nexport function randomElem<TArr>(array: TArr[], multi: number): TArr[];\nexport function randomElem<TArr>(array: TArr[], multi?: number): TArr | undefined | TArr[] {\n if (multi === undefined) {\n if (array.length === 0) return undefined;\n return getSingleElement(array);\n }\n\n if (multi && array.length === 0) return [];\n\n // Multiple samples\n const result = new Array<TArr>(multi);\n for (let i = 0; i < multi; i++) {\n result[i] = getSingleElement(array);\n }\n return result;\n}\n\nfunction getSingleElement<TArr>(array: TArr[]): TArr {\n const randomIndex = randomInt(0, array.length - 1);\n return array[randomIndex];\n}","/* eslint-disable no-bitwise */\nconst shiftLeft20Bits = 2 ** 20;\nconst shiftRight52Bits = 2 ** -52;\n\n/**\n * Generates a random float between two given numbers, including those numbers.\n * \n * It uses `crypto.getRandomValues` to generate the random number.\n * @example\n * randomFloat(1, 10) \n * // => 1.123456789\n * \n * @param min The smallest float that can be generated.\n * @param max The largest float that can be generated.\n * \n * @returns A random float between `min` and `max`, including `min` and `max`.\n */\n\nexport function randomFloat(min: number, max: number): number {\n if (min >= max) {\n throw new Error('max must be greater than min');\n }\n const range = max - min;\n const randomBuffer = new Uint32Array(2);\n crypto.getRandomValues(randomBuffer);\n\n // keep all 32 bits of the the first, top 20 of the second for 52 random bits\n const mantissa = (randomBuffer[0] * shiftLeft20Bits) + (randomBuffer[1] >>> 12);\n\n // shift all 52 bits to the right of the decimal point\n const randomFloat = mantissa * shiftRight52Bits;\n return min + (randomFloat * range);\n}","import { randomInt } from './randomInt.js';\n\nconst DEFAULT_CHARSET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n\n/**\n * Generates a random string of the specified length.\n * The default charset is alphanumeric characters.\n * \n * It uses `crypto.getRandomValues` to generate the random string.\n * \n * @example\n * randomString(8);\n * // => \"JWw1p6rD\"\n *\n * randomString(16, 'abc');\n * // => \"cbaacbabcabccabc\"\n * @param length The length of the string to generate.\n * @param charSet The set of characters to use when generating the string. Defaults to alphanumeric characters.\n * @returns A random string of the specified length.\n */\n\nexport function randomString(length: number, charSet = DEFAULT_CHARSET): string {\n if (charSet.length <= 0) return '';\n\n let result = '';\n for (let index = 0; index < length; index++) {\n const randomIndex = randomInt(0, charSet.length - 1);\n result += charSet[randomIndex];\n }\n\n return result;\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\ntype Tail<T extends unknown[]> = T extends [infer _Head, ...infer Tail] ? Tail : never;\n\n/**\n * Transforms a function that takes a function as first argument into a decorator function.\n * \n * @example\n * ```typescript\n * function log(func: Function, message: string) {\n * return function (...args: unknown[]) {\n * console.log(message);\n * return func(...args);\n * };\n * }\n * \n * const logger = toDecorator(log);\n * \n * class TestClass {\n * @logger(\"Hello world!\")\n * testMethod() {\n * return 1; \n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(); \n * // => Log \"Hello World\" and return 1\n * ```\n * @param func The function to transform.\n * @returns A decorator function that can be used to decorate a method.\n */\n\nexport function toDecorator<TFunc extends GenericFunction<TFunc>>(func: TFunc) {\n return function (...args: Tail<Parameters<TFunc>>) {\n return function (target: unknown, key: string, descriptor: PropertyDescriptor) {\n const creatorArgs = [descriptor.value, ...args] as Parameters<TFunc>;\n descriptor.value = func(...creatorArgs);\n };\n };\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a debounced version of a function. Only calling it after a specified amount of time has passed without any new calls.\n * \n * **Methods:** \n * - `cancel` will cancel the next invocation of the debounced function. \n * - `flush` will immediately invoke the debounced function and cancel any pending invocations. \n * \n * This function can be used as a decorator with {@link decDebounce}.\n * \n * @example\n * const sayHello = (name: string) => console.log(`Hello, ${name}!`);\n * const debouncedSayHello = debounce(sayHello, 200);\n * \n * debouncedSayHello(\"John\");\n * debouncedSayHello(\"Jane\");\n * // => Only the second invocation of `debouncedSayHello` is executed, after a delay of 200ms.\n * @param func The function to debounce.\n * @param wait The number of milliseconds to wait before invoking `func`.\n * @returns A debounced version of `func` with `cancel` and `flush` methods.\n */\n\nexport function debounce<TFunc extends GenericFunction<TFunc>>(func: TFunc, wait: number): TFunc & {\n cancel: () => void;\n flush: () => void;\n} {\n let timeoutId: NodeJS.Timeout | undefined;\n const debounced = function (this: unknown, ...args: Parameters<TFunc>) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => func.apply(this, args), wait);\n };\n\n /** Cancels the next invocation of the debounced function. */\n debounced.cancel = function () {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n };\n\n /** Immediately invokes the debounced function and cancels any pending invocations. */\n debounced.flush = function (this: unknown, ...args: Parameters<TFunc>) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n func.apply(this, args);\n };\n\n return debounced as TFunc & { cancel: () => void; flush: () => void };\n}","import { toDecorator } from '@decorator/toDecorator.js';\nimport { debounce } from '@function/debounce.js';\n\n/**\n * Debouces the decorated function. Only calling it after a specified amount of time has passed without any new calls.\n * \n * Look at {@link debounce} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decDebounce(100)\n * testMethod(str: string) {\n * console.log(\"Debounced:\", str);\n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(\"Hello\");\n * instance.testMethod(\"World\");\n * // => Only the second invocation of `debouncedSayHello` is executed, after a delay of 1000ms.\n * ```\n * @param wait Milliseconds to wait before invoking the decorated function after the last invocation.\n */\n\nexport function decDebounce(wait: number) {\n return toDecorator(debounce)(wait);\n}\n","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a function that invokes the given function as long as it's called `<= n` times.\n * \n * Subsequent calls to the created function return the result of the last `func` invocation.\n *\n * This function can be used as a decorator with {@link decMaxCalls}.\n * @example\n * let count = 0;\n * const addCount = () => ++count;\n *\n * // Allow addCount to be invoked twice.\n * const limitAddCount = maxCalls(addCount, 2)\n *\n * limitAddCount() // => 1\n * limitAddCount() // => 2\n * limitAddCount() // => 2\n * // => `limitAddCount` is invoked twice and the result is cached.\n * @param n The number of calls before the cached result is returned.\n * @param func The function to restrict.\n * @returns Returns the new restricted function.\n */\n\nexport function maxCalls<TFunc extends GenericFunction<TFunc>>(func: TFunc, n: number): TFunc {\n let count = 0;\n let result: ReturnType<TFunc>;\n return function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> {\n if (count < n) {\n count += 1;\n result = func.apply(this, args);\n }\n return result;\n } as TFunc;\n}\n","import { toDecorator } from '@decorator/toDecorator.js';\nimport { maxCalls } from '@function/maxCalls.js';\n\n/**\n * Only invokes the decorated function as long as it's called `<= n` times. \n * Subsequent calls to the decorated function return the result of the last invocation.\n * \n * Look at {@link maxCalls} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * private count = 0;\n * @decMaxCalls(2)\n * testMethod() {\n * return ++this.count;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(); // => 1 \n * instance.testMethod(); // => 2\n * instance.testMethod(); // => 2\n * ```\n * @param n The number of calls before the cached result is returned.\n */\n\nexport function decMaxCalls(n: number) {\n return toDecorator(maxCalls)(n);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\nconst defaultResolver = (...args: unknown[]) => JSON.stringify(args);\n\n/**\n * Creates a function that memoizes the result of a given function.\n * \n * The cache key is determined by the `resolver` or by the arguments from the function call.\n *\n * **Options:**\n * - `resolver` A function that determines the cache key based on the arguments provided.\n * - `ttl` the time to live for the cache entries in milliseconds.\n * \n * **Properties:**\n * - `cache` The cache is an instance of `Map` and can be used to clear or inspect the cache. \n * It can be replaced by a custom cache that matches the `Map` interface.\n * \n * \n * This function can be used as a decorator with {@link decMemoize}.\n * \n * @example\n * ```typescript\n * function fibonacci(n: number) {\n * if (n <= 1) return n;\n * return fibonacci(n - 1) + fibonacci(n - 2);\n * }\n *\n * const memoizedFib = memoize(fibonacci, { ttl: 1000 })\n * \n * memoizedFib(40) // => 102334155\n * memoizedFib(40) // => 102334155 (cache hit)\n * setTimeout(() => memoizedFib(40), 1000) // => 102334155 (cache miss)\n * \n * // Cached values are exposed as the `cache` property.\n * memoizedFib.cache.get(\"40\") // => [value, timestamp]\n * memoizedFib.cache.set(\"40\", [1234, Date.now()])\n * memoizedFib.cache.clear()\n * \n * // This is the default way to create cache keys.\n * const defaultResolver = (...args: unknown[]) => JSON.stringify(args)\n * ```\n * @param func The function to have its output memoized.\n * @param options The options object with optional `resolver` and `ttl` parameters.\n * @param options.resolver - A function that determines the cache key for storing the result based on the arguments provided.\n * @param options.ttl - The time to live for the cache in milliseconds.\n * @template TFunc The type of the function to memoize.\n * @template Cache The type of the cache storage.\n * @returns Returns the new memoized function.\n */\n\nexport function memoize<TFunc extends GenericFunction<TFunc>, Cache extends Map<string, [ReturnType<TFunc>, number]>>(\n func: TFunc, options: { resolver?: (...args: Parameters<TFunc>) => string, ttl?: number; } = {}\n): TFunc & { cache: Cache } {\n const resolver = options.resolver ?? defaultResolver;\n const ttl = options.ttl;\n const cache = new Map() as Cache;\n\n const memoizedFunc = function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> {\n const key = resolver(...args);\n if (cache.has(key)) {\n const [cacheResult, cacheTime] = cache.get(key)!;\n if (ttl === undefined || (Date.now() - cacheTime < ttl)) {\n return cacheResult;\n }\n }\n const result = func.apply(this, args);\n cache.set(key, [result, Date.now()]);\n return result;\n };\n\n memoizedFunc.cache = cache;\n return memoizedFunc as TFunc & { cache: Cache };\n} ","import { toDecorator } from '@decorator/toDecorator.js';\nimport { memoize } from '@function/memoize.js';\n\n/**\n * Memoizes the decorated function. \n * The cache key is either determined by the provided resolver or by the arguments used in the memoized function.\n * \n * **Options:**\n * - `resolver` A function that determines the cache key for storing the result based on the arguments provided.\n * - `ttl` sets the time to live for the cache in milliseconds. After `ttl` milliseconds, the next call to the memoized function will result in a cache miss.\n * \n * Look at {@link memoize} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decMemoize({ ttl: 1000 })\n * testMethod(a: number, b: number) {\n * return a + b;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(1, 2); // => 3\n * instance.testMethod(1, 2); // => 3 (cached)\n * \n * // After 1 second:\n * instance.testMethod(1, 2); // => 3 (cache miss)\n * ```\n * @param options The options object.\n * @param options.resolver - A function that determines the cache key for storing the result based on the arguments provided.\n * @param options.ttl - The time to live for the cache in milliseconds.\n */\n\nexport function decMemoize(options: Parameters<typeof memoize>[1] = {}) {\n return toDecorator(memoize)(options);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Creates a function that invokes the given function once it's called more than `n` times. \n * Returns undefined until the minimum call count is reached.\n * \n * This function can be used as a decorator with {@link decMinCalls}.\n * @example\n * const caution = () => console.log(\"Caution!\");\n * const limitedCaution = minCalls(caution, 2);\n *\n * limitedCaution()\n * limitedCaution()\n * limitedCaution()\n * // => `caution` is invoked on the third call.\n * @param n The number of calls before the given function is invoked.\n * @param func The function to restrict.\n * @returns Returns the new restricted function.\n */\n\nexport function minCalls<TFunc extends GenericFunction<TFunc>>(func: TFunc, n: number) {\n let count = 1;\n return function (this: unknown, ...args: Parameters<TFunc>): ReturnType<TFunc> | undefined {\n if (count > n) {\n return func.apply(this, args);\n }\n count += 1;\n };\n}","import { toDecorator } from '@decorator/toDecorator.js';\nimport { minCalls } from '@function/minCalls.js';\n\n/** \n * Only invokes the decorated function after it's called more than `n` times.\n * \n * Look at {@link minCalls} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * @example\n * ```typescript\n * class TestClass {\n * @decMinCalls(2)\n * testMethod() {\n * return 1;\n * }\n * }\n * const instance = new TestClass();\n * instance.testMethod(); // => undefined\n * instance.testMethod(); // => undefined\n * instance.testMethod(); // => 1\n * ```\n * @param n The number of calls before the decorated function is invoked.\n */\n\nexport function decMinCalls(n: number) {\n return toDecorator(minCalls)(n);\n}","import type { GenericFunction } from '@type/GenericFunction.js';\n\n/**\n * Generates a function that invokes the given function at most once per every `wait` milliseconds.\n * \n * This function can be used as a decorator with {@link decThrottle}.\n * @example\n * const throttled = throttle(() => console.log(\"Throttled!\"), 1000);\n * \n * throttled();\n * throttled();\n * // => \"Throttled!\" is logged once per second.\n * @param func The function to throttle.\n * @param wait The number of milliseconds to throttle invocations to.\n * @returns Returns the new throttled function.\n */\n\n\nexport function throttle<TFunc extends GenericFunction<TFunc>>(func: TFunc, wait: number): TFunc {\n let inThrottle = false;\n return function (this: unknown, ...args: Parameters<TFunc>) {\n if (!inThrottle) {\n func.apply(this, args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), wait);\n }\n } as TFunc;\n}\n \n","import { toDecorator } from '@decorator/toDecorator.js';\nimport { throttle } from '@function/throttle.js';\n\n/**\n * The decorated function is invoked at most once per every `wait` milliseconds.\n * \n * Look at {@link throttle} for the non-decorator version.\n * \n * *Requires TypeScript >=5.0 or `experimentalDecorators` flag enabled.*\n * \n * @example\n * ```typescript\n * class TestClass {\n * @decThrottle(1000)\n * testMethod() {\n * console.log(\"Throttled!\");\n * }\n * }\n * \n * const instance = new TestClass();\n * instance.testMethod(); // => \"Throttled!\" is logged once per second.\n * instance.testMethod(); // nothing happens\n * ```\n * @param wait The number of milliseconds to wait between invocations.\n */\n\nexport function decThrottle(wait: number) {\n return toDecorator(throttle)(wait);\n}","/**\n * Invokes a function `n` times, returning an array of the results of\n * each invocation.\n * \n * @example\n * times(index => console.log(\"Run\", index), 3)\n * // => \"Run 0\" | \"Run 1\" | \"Run 2\"\n * times(Math.random, 3)\n * // => [0.123, 0.456, 0.789]\n * times(() => 0, 4)\n * // => [0, 0, 0, 0]\n * @param n The number of times to invoke `func`.\n * @param func The function invoked per iteration.\n * @returns Returns an array of results.\n */\n\nexport function times<TInput>(func: (index: number) => TInput, n: number): TInput[] {\n const result: TInput[] = [];\n for (let i = 0; i < n; i++) {\n result.push(func(i));\n }\n return result;\n}","/**\n * Calculates the sum of an array of numbers.\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * sum([1, 2, 3, 4, 5]) // => 15\n * \n * @param numbers The input array of numbers\n * @returns The sum of the input array \n */\n\nexport function sum(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n return numbers.reduce((total, current) => total + current, 0);\n}","import { sum } from '@number/sum.js';\n\n/**\n * Calculates the average of an array of numbers\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * average([1, 2, 3, 4, 5]) // => 3\n * \n * @param numbers The input array of numbers\n * @returns The average of the input array, or NaN if the input array is empty\n */\n\nexport function average(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n return sum(numbers) / numbers.length;\n}","/**\n * Calculates the median of an array of numbers\n * \n * Returns `NaN` if the input array is empty.\n * @example\n * median([1, 2, 3, 4, 5]) // => 3\n * median([1, 2, 3, 4, 5, 6]) // => 3.5\n * \n * @param numbers The input array of numbers\n * @returns The median of the input array\n */\n\nexport function median(numbers: readonly number[]): number {\n if (numbers.length === 0)\n return NaN;\n const sortedArray = [...numbers].sort((a, b) => a - b);\n const mid = Math.floor(sortedArray.length / 2);\n return sortedArray.length % 2 === 0 ? ((sortedArray[mid - 1] + sortedArray[mid]) / 2) : sortedArray[mid];\n}","/**\n * Rounds a number to the given precision.\n *\n * @example\n * round(1.23456, 2); // => 1.23\n * round(1.235, 1); // => 1.2\n * round(1234.56); // => 1234.56\n * \n * @param number The number to be rounded.\n * @param precision The number of decimal places to round to. Defaults to 2.\n * @returns The rounded number.\n */\n\nexport function round(number: number, precision = 2): number {\n const factor = Math.pow(10, precision);\n return Math.round((number + Number.EPSILON) * factor) / factor;\n}","import type { PlainObject } from '@type/PlainObject.js';\n\n/**\n * Checks if the value is a plain object.\n * \n * @example\n * isPlainObject({}) // => true\n * isPlainObject({ a: 1 }) // => true\n * isPlainObject(null) // => false\n * isPlainObject('1') // => false\n * isPlainObject([]) // => false\n * isPlainObject(new Function()) // => false\n * isPlainObject(new Date()) // => false\n * @param value The value to check\n * @returns Boolean indicating if the value is a plain object\n */\n\nexport function isPlainObject(value: unknown): value is PlainObject {\n return value?.constructor === Object;\n}","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\n/**\n * Flattens an object into a single level object.\n * \n * @example\n * const obj = { a: { b: 2, c: [{ d: 3 }, { d: 4 }] } };\n * flatKeys(obj);\n * // => { 'a.b': 2, 'a.c[0].d': 3, 'a.c[1].d': 4 }\n * \n * @param obj The object to flatten.\n * @template TObj The type of the object to flatten.\n * @returns A new object with flattened keys.\n */\n\nexport function flatKeys<TObj extends PlainObject>(obj: TObj): Record<string, unknown> {\n const flatObject: Record<string, unknown> = {};\n \n for (const [key, value] of Object.entries(obj)) {\n addToResult(key, value, flatObject);\n }\n \n return flatObject;\n}\n\nfunction addToResult(prefix: string, value: unknown, flatObject: Record<string, unknown>) {\n if (isPlainObject(value)) {\n const flatObj = flatKeys(value);\n for (const [flatKey, flatValue] of Object.entries(flatObj)) {\n flatObject[`${prefix}.${flatKey}`] = flatValue;\n }\n } else if (Array.isArray(value)) {\n for (const [index, element] of value.entries()) {\n addToResult(`${prefix}[${index}]`, element, flatObject);\n }\n\n } else {\n flatObject[prefix] = value;\n }\n}\n","import type { ArrayMinLength } from '@type/ArrayMinLength.js';\nimport type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\n/**\n * This function combines two or more objects into a single new object. Arrays and other types are overwritten.\n * \n * @example\n * // ---- Nested objects are merged ----\n * merge({ a: 1 }, { b: 2 }, { c: 3, d: { e: 4 } }) \n * // => { a: 1, b: 2, c: 3, d: { e: 4 } }\n *\n * // ---- Other types are overwritten ----\n * merge({ a: [1, 2] }, { a: [3, 4] })\n * // => { a: [3, 4] }\n * \n * merge({ a: 1 }, { a: \"Yes\" })\n * // => { a: \"Yes\" }\n * @param target The target object\n * @param sources The source objects\n * @template TTarget The type of the target object\n * @template TSources The type of the source objects\n * @returns A new merged object\n */\n\nexport function merge<TTarget extends PlainObject, TSources extends ArrayMinLength<PlainObject, 1>>(target: TTarget, ...sources: TSources): MergeDeepObjects<[TTarget, ...TSources]> {\n const targetCopy = { ...target };\n for (const source of sources) {\n for (const [key, value] of Object.entries(source)) {\n (targetCopy as PlainObject)[key] = isPlainObject(value) && isPlainObject(targetCopy[key]) \n ? merge(targetCopy[key] as PlainObject, value) \n : value;\n }\n }\n return targetCopy as MergeDeepObjects<[TTarget, ...TSources]>; \n}\n\ntype OptionalPropertyNames<T> =\n { [K in keyof T]-?: (PlainObject extends { [P in K]: T[K] } ? K : never) }[keyof T];\n\ntype SpreadProperties<L, R, K extends keyof L & keyof R> =\n { [P in K]: L[P] | Exclude<R[P], undefined> };\n\ntype Id<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;\n\ntype SpreadTwo<L, R> = Id<\n& Pick<L, Exclude<keyof L, keyof R>>\n& Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>>\n& Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>>\n& SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>\n>;\n\ntype MergeDeepObjects<A extends readonly [...unknown[]]> = A extends [infer L, ...infer R] ?\n SpreadTwo<L, MergeDeepObjects<R>> : unknown;\n","import type { PlainObject } from '@type/PlainObject.js';\n\n/**\n * Creates an object composed of the picked `object` properties.\n *\n * @example\n * const object = { 'a': 1, 'b': '2', 'c': 3 }\n *\n * pick(object, ['a', 'c'])\n * // => { 'a': 1, 'c': 3 }\n * @param object The source object.\n * @param keysToPick The property paths to pick.\n * @template TObj The type of the object.\n * @returns Returns the new object.\n */\n\nexport function pick<TObj extends PlainObject, Key extends keyof TObj>(object: TObj, keysToPick: Key[]): Pick<TObj, Key> {\n const result = {} as Pick<TObj, Key>;\n for (const key of keysToPick) {\n result[key] = object[key];\n }\n return result;\n}\n","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { pick } from './pick.js';\n\n/**\n * Omit specified keys from an object\n *\n * @example\n * const obj = {a: 1, b: 2, c: 3};\n * omit(obj, ['a', 'b']);\n * // => {c: 3}\n *\n * @param object The object to filter\n * @param keysToOmit The keys to exclude from the returned object\n * @template TObj The type of the object\n * @returns - An object without the specified keys\n */\n\nexport function omit<TObj extends PlainObject, Key extends keyof TObj>(object: TObj, keysToOmit: Key[]): Omit<TObj, Key> {\n const keys = Object.keys(object);\n const filteredKeys = keys.filter(key => !keysToOmit.includes(key as Key)) as Exclude<keyof TObj, Key>[];\n\n return pick(object, filteredKeys);\n}","import type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from '@validate/isPlainObject.js';\n\nconst validPathRegex = /^(?:[^.[\\]]+(?:\\[\\d+])*(?:\\.|\\[\\d+]))+(?:[^.[\\]]+(?:\\[\\d+])*)+$/;\nconst pathSplitRegex = /\\.|(?=\\[)/g;\nconst matchBracketsRegex = /[[\\]]/g;\n\n/**\n * Sets the value at path of object. If a portion of path doesn’t exist, it’s created.\n * \n * @example\n * const obj = { a: { b: 2 } };\n * set(obj, 'a.c', 1);\n * // => { a: { b: 2, c: 1 } }\n * \n * // `[number]` can be used to access array elements\n * set(obj, 'a.c[0]', 'hello');\n * // => { a: { b: 2, c: ['hello'] } }\n * \n * // numbers with dots are treated as keys\n * set(obj, 'a.c.0.d', 'world');\n * // => { a: { b: 2, c: { 0: { d: 'world' } } }\n * \n * // supports numbers in keys\n * set(obj, 'a.e0.a', 1);\n * // => { a: { e0: { a: 1 } } }\n * \n * @param obj The object to modify.\n * @param path The path of the property to set.\n * @param value The value to set.\n * @template TObj The type of the object.\n * @returns The modified object.\n */\n\nexport function set(obj: PlainObject, path: string, value: unknown): PlainObject {\n if (!validPathRegex.test(path))\n throw new Error('Invalid path, look at the examples for the correct format.');\n\n const pathParts = path.split(pathSplitRegex);\n let currentObj: PlainObject = obj;\n for (let index = 0; index < pathParts.length; index++) {\n const key = pathParts[index].replace(matchBracketsRegex, '');\n\n if (index === pathParts.length - 1) {\n currentObj[key] = value;\n break;\n }\n\n const nextElemIn = pathParts[index + 1].startsWith('[') ? 'array' : 'object';\n if (currentObj[key] === undefined) {\n currentObj[key] = nextElemIn === 'array' ? [] : {};\n } else if (nextElemIn === 'array' && !Array.isArray(currentObj[key])) {\n currentObj[key] = [];\n } else if (nextElemIn === 'object' && !isPlainObject(currentObj[key])) {\n currentObj[key] = {};\n }\n currentObj = currentObj[key] as PlainObject;\n }\n\n return obj;\n}","/**\n * A class for managing a queue of async functions that runs a set number concurrently. \n * If for example you have 10 async functions and you want to run 3 at a time, you can use this class.\n * \n * If the queue is paused, the queue will not run any more async functions until it is resumed.\n * \n * **Methods:**\n * - `add` - adds a async function or array of functions to the queue. Returns a promise that resolves when the added function(s) finish.\n * - `clear` - clears the queue.\n * - `pause` - pauses the queue.\n * - `resume` - resumes the queue. \n * - `getQueue` - returns the current queue.\n * - `isPaused` - returns whether the queue is paused.\n * \n * @example\n * // Create a queue that can run 3 tasks concurrently\n * const queue = new Queue(3);\n * \n * queue.add(() => fetch('https://example.com'));\n * \n * queue.add(async () => {\n * const response = await fetch('https://example.com');\n * return response.json();\n * });\n * \n * // Add an array of tasks to the queue and wait for them to resolve\n * await queue.add([\n * () => fetch('https://apple.com'),\n * () => fetch('https://microsoft.com')\n * ]);\n * // => [Response, Response]\n */\n\nexport class Queue {\n private running = 0;\n private maxConcurrent: number;\n private paused = false;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private queue: { asyncFn: () => Promise<any>, resolve: (value: any) => void, reject: (reason?: any) => void }[] = [];\n\n /**\n * @constructor\n * @param maxConcurrent The maximum number of async functions to run concurrently.\n */\n constructor(maxConcurrent: number) {\n this.maxConcurrent = maxConcurrent;\n }\n\n /**\n * Add aync functions or an array of async functions to the queue.\n * \n * @param asyncFn The aync function(s) to add to the queue.\n * @returns A promise that resolves when the added function(s) finishes.\n */\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn): Promise<TProm>;\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn[]): Promise<TProm[]>;\n add<TProm, TAsyncFn extends () => Promise<TProm>>(asyncFn: TAsyncFn | TAsyncFn[]): Promise<TProm> | Promise<TProm[]> {\n if (Array.isArray(asyncFn)) {\n const promises = asyncFn.map((fn) => this.buildWaitingPromise(fn));\n return Promise.all(promises);\n } else {\n return this.buildWaitingPromise(asyncFn);\n } \n }\n\n private buildWaitingPromise<TProm>(asyncFn: () => Promise<TProm>): Promise<TProm> {\n return new Promise((resolve, reject) => {\n this.queue.push({ asyncFn, resolve, reject });\n this.run();\n });\n } \n\n private run() {\n while (this.queue.length > 0 && this.running < this.maxConcurrent && !this.paused) {\n this.running++;\n const queueElement = this.queue.shift()!;\n void queueElement.asyncFn()\n .then((result) => {\n queueElement.resolve(result);\n }).catch((error) => {\n queueElement.reject(error);\n }).finally(() => {\n this.running--;\n this.run();\n });\n }\n }\n\n /** Removes all the tasks from the queue */\n clear() {\n for (const queueElement of this.queue) {\n queueElement.reject(new Error('Queue cleared'));\n }\n this.queue = [];\n }\n\n /** Pauses the execution of the queue */\n pause() {\n this.paused = true;\n }\n\n /** Resumes the execution of the tasks in the queue */\n resume() {\n this.paused = false;\n this.run();\n }\n\n /** Return the tasks added to the queue */\n getQueue() {\n return this.queue.map((queueElement) => queueElement.asyncFn);\n }\n\n /** Returns whether the queue is paused */\n isPaused() {\n return this.paused;\n }\n\n}\n","/**\n * Similar to [Promise.race](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race?retiredLocale=de) \n * but allows to specify how many promises to wait for.\n *\n * @example\n * const prom1 = Promise.resolve(1);\n * const prom2 = new Promise(resolve => setTimeout(resolve, 100, 2));\n * const prom3 = Promise.resolve(3);\n * \n * const firstTwo = await races(2, prom1, prom2, prom3);\n * // => [1, 3]\n * \n * @template TRes The type of the result of the promises.\n * @param waitFor The number of promises to wait for.\n * @param promises The promises to wait for.\n * @returns A promise that resolves an array of the results of the first n promises.\n */\n\nexport function races<TRes>(waitFor: number, ...promises: Promise<TRes>[]): Promise<TRes[]> {\n return new Promise((resolve, reject) => {\n if (promises.length < waitFor)\n waitFor = promises.length;\n\n const results: TRes[] = [];\n let resolved = 0;\n for (const promise of promises) {\n promise.then((value) => {\n results.push(value);\n resolved++;\n if (resolved >= waitFor) {\n resolve(results);\n }\n }).catch((error) => {\n reject(error);\n });\n }\n });\n}","/**\n * Sleeps for the given amount of time.\n *\n * @example\n * await sleep(1000);\n * // => Waits for 1 second.\n * @param ms Amount of time to sleep in milliseconds.\n * @returns A promise that resolves after the given amount of time.\n */\nexport function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}","/* eslint-disable no-await-in-loop */\nimport { sleep } from '@promise/sleep.js';\n\n/**\n * Retry a function until it succeeds or the maximum number of retries is reached.\n * \n * Default maxRetries: `5`. \n * Default backoff: `2^retries * 100ms` (100, 200, 400, 800, 1600, 3200, ...)\n *\n * @example\n * await retry(() => fetch('https://example.com'));\n * \n * // ---- Advanced example ----\n * const fetchSite = async () => {\n * const response = await fetch('https://example.com');\n * if(!response.ok)\n * throw new Error('Failed to fetch');\n * }\n * \n * const logger = (error: unknown, retry?: number) => console.log(\"Retrying\", retry, error);\n * \n * await retry(fetchSite, { maxRetries: 3, backoff: retries => retries * 1000, onRetry: logger });\n * // => Will retry 3 times with a 1 second delay between each retry.\n * // => Will log the error and retry number.\n * \n * @param func The function to retry.\n * @param options The options for the retry.\n * @param options.maxRetries The maximum number of retries. Defaults to `5`.\n * @param options.backoff The backoff function to use. Defaults to `2^retries * 100`.\n * @param options.onRetry The function to call when a retry is attempted. It will be called with the error and the attempt number.\n * @template TRes The type of the result of the function.\n * @returns A promise that resolves when the function succeeds.\n */\n\nexport async function retry<TRes>(\n func: () => Promise<TRes>, \n options?: { \n maxRetries?: number,\n backoff?: ((retries: number) => number),\n onRetry?: (error?: unknown, attempted?: number) => void\n }\n): Promise<TRes> {\n const backOffFn = options?.backoff ?? (retries => (2 ** retries) * 100);\n const maxRetries = options?.maxRetries ?? 5;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n const onRetry = options?.onRetry ?? (() => {});\n let retries = 0;\n let lastError: unknown;\n\n while (retries <= maxRetries) {\n try {\n if (retries > 0)\n onRetry(lastError, retries);\n return await func();\n } catch (error) {\n lastError = error;\n retries++;\n if (retries > maxRetries) {\n throw error;\n }\n await sleep(backOffFn(retries));\n }\n /* c8 ignore next 2 */\n }\n throw new Error('Retry terminated without success, this should never happen');\n}","/**\n * Returns a new promise that will reject with an error after a specified timeout. \n *\n * @example\n * try {\n * await timeout(fetch('https://example.com'), 1000);\n * } catch (error) {\n * console.log(error.message);\n * // => 'Promise timed out after 1000ms'\n * }\n * @template TRes - The type of the resolved value.\n * @param promise The promise to wrap.\n * @param timeout The timeout in milliseconds.\n * \n * @returns A new promise that will reject with an error after the specified timeout.\n */\nexport function timeout<TRes>(promise: Promise<TRes>, timeout: number): Promise<TRes> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error(`Promise timed out after ${timeout}ms`));\n }, timeout);\n \n promise.then(\n (result) => {\n clearTimeout(timeoutId);\n resolve(result);\n },\n (error) => {\n clearTimeout(timeoutId);\n reject(error);\n }\n );\n });\n}","/**\n * Attempts to execute a promise and returns an array with the result or error.\n * \n * This is useful for handling errors in async functions without try/catch blocks.\n * \n * @example\n * ```typescript\n * const [data, error] = await tryCatch(fetch('https://example.com/api'));\n * if (error)\n * console.error(`Error: ${error.message}`);\n * ```\n * @param promise A Promise to be executed.\n * @returns A Promise that resolves to an array containing the result or error. \n * If the Promise executes successfully, the array contains the result and a null error. \n * If the Promise throws an error, the array contains undefined for the result and the error object.\n *\n * @template TRes The type of the result.\n */\n\nexport async function tryCatch<TRes>(promise: Promise<TRes>): Promise<[TRes, undefined] | [undefined, Error]> {\n try {\n const data = await promise;\n return [data, undefined];\n } catch (error) {\n if (error instanceof Error)\n return [undefined, error];\n\n throw error;\n }\n}","// Split non-alphanumeric characters with spaces and deal with camel/PascalCase\nconst splitWordsRegex = new RegExp(\n '[^\\\\dA-Za-z]' + // match any character that is not a letter or a digit\n '|' + // or\n '(?<=[a-z])' + // lookbehind for a lowercase letter\n '(?=[A-Z])' + // lookahead for an uppercase letter\n '|' + // or\n '(?<=[A-Z])' + // lookbehind for an uppercase letter\n '(?=[A-Z][a-z])' // lookahead for an uppercase letter followed by a lowercase letter\n);\n\n/**\n * Split a string into words. Can deal with camelCase, PascalCase & snake_case.\n * \n * @example\n * splitWords('camelCase')\n * // => ['camel', 'Case']\n * \n * splitWords('PascalCase')\n * // => ['Pascal', 'Case']\n * \n * splitWords('hello_world-123')\n * // => ['hello', 'world', '123']\n * \n * @param str The string to split into words.\n * @returns An array of words.\n */\n\nexport function splitWords(str: string): string[] {\n return str.split(splitWordsRegex).filter(Boolean);\n}","const accentControlRegex = /[\\u0300-\\u036F]/g;\n\n/**\n * Deburrs a string by converting\n * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n * letters to basic Latin letters and removing\n * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n *\n * @example\n * deburr('déjà vu')\n * // => 'deja vu'\n * @param str The string to deburr.\n * @returns Returns the deburred string.\n */\n\nexport function deburr(str: string): string {\n return str.normalize('NFD').replace(accentControlRegex, '');\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts `string` to camelCase.\n *\n * @example\n * camelCase('Foo Bar')\n * // => 'fooBar'\n * camelCase('--foo-bar--')\n * // => 'fooBar'\n * camelCase('__FOO_BAR__')\n * // => 'fooBar'\n * @param str The string to convert.\n * @returns Returns the camel cased string.\n */\n\nexport function camelCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n\n let camelCase = '';\n for (const [index, word] of words.entries()) {\n camelCase += index === 0 \n ? word.toLowerCase() \n : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n }\n\n return camelCase;\n}","/**\n * Converts the first character of a string to upper case and the remaining to lower case.\n *\n * @example\n * capitalize('FRED')\n * // => 'Fred'\n * @param str The string to capitalize.\n * @returns Returns the capitalized string.\n */\n\nexport function capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","const charRegex = /[\"&'<>]/g;\nconst escapeChars = new Map([\n ['&', '&amp;'],\n ['<', '&lt;'],\n ['>', '&gt;'],\n ['\\'', '&#39;'],\n ['\"', '&quot;']\n]);\n\n/**\n * Converts the characters `&`, `<`, `>`, `\"` and `'` in a string to their corresponding HTML entities.\n *\n * @example\n * escapeHtml('fred, barney, & pebbles')\n * // => 'fred, barney, &amp; pebbles'\n * @param str The string to escape.\n * @returns Returns the escaped string.\n */\n\nexport function escapeHtml(str: string): string {\n return str.replace(charRegex, char => escapeChars.get(char)!);\n}\n","const escapleCharsRegex = /[$()*+.?[\\\\\\]^{|}]/g;\n\n/**\n * Escapes the `RegExp` special characters `^`, `$`, `\\`, `.`, `*`, `+`,\n * `?`, `(`, `)`, `[`, `]`, `{`, `}`, and `|` in a string.\n *\n * @example\n * escapeRegExp('[moderndash](https://moderndash.io/)')\n * // => '\\[moderndash\\]\\(https://moderndash\\.io/\\)'\n * @param str The string to escape.\n * @returns Returns the escaped string.\n */\n\nexport function escapeRegExp(str: string): string {\n return str.replace(escapleCharsRegex, '\\\\$&');\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to kebab-case.\n *\n * @example\n * kebabCase('Foo Bar')\n * // => 'foo-bar'\n * kebabCase('fooBar')\n * // => 'foo-bar'\n * kebabCase('__FOO_BAR__')\n * // => 'foo-bar'\n * \n * @param str The string to convert.\n * @returns Returns the kebab cased string.\n */\n\nexport function kebabCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let kebabCase = '';\n for (const word of words) {\n kebabCase += word.toLowerCase() + '-';\n }\n return kebabCase.slice(0, -1);\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n\n/**\n * Converts a string to PascalCase.\n *\n * @example\n * pascalCase('Foo Bar')\n * // => 'FooBar'\n * pascalCase('fooBar')\n * // => 'FooBar'\n * pascalCase('__FOO_BAR__')\n * // => 'FooBar'\n * \n * @param str The string to convert.\n * @returns Returns the pascal cased string.\n */\n\nexport function pascalCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let pascalCase = '';\n for (const word of words) {\n pascalCase += word.charAt(0).toUpperCase() + word.slice(1);\n }\n return pascalCase;\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to snake_case.\n *\n * @example\n * snakeCase('Foo Bar')\n * // => 'foo_bar'\n * snakeCase('fooBar')\n * // => 'foo_bar'\n * snakeCase('--FOO-BAR--')\n * // => 'foo_bar'\n * snakeCase('foo2bar')\n * // => 'foo_2_bar'\n * \n * @param str The string to convert.\n * @returns Returns the snake cased string.\n */\n\nexport function snakeCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let snakeCase = '';\n for (const word of words) {\n if (snakeCase.length > 0) {\n snakeCase += '_';\n }\n snakeCase += word.toLowerCase();\n }\n return snakeCase;\n}\n","import { splitWords } from '@string/splitWords';\n\nimport { deburr } from './deburr.js';\n\n/**\n * Converts a string to Title Case.\n *\n * @example\n * titleCase('--foo-bar--')\n * // => 'Foo Bar'\n * titleCase('fooBar')\n * // => 'Foo Bar'\n * titleCase('__FOO_BAR__')\n * // => 'Foo Bar'\n * titleCase('HélloWorld')\n * // => 'Hello World'\n * @param str The string to convert.\n * @returns Returns the title cased string.\n */\n\nexport function titleCase(str: string): string {\n str = deburr(str);\n const words = splitWords(str);\n let titleCase = '';\n for (const word of words) {\n titleCase += word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() + ' ';\n }\n return titleCase.trimEnd();\n}\n","const htmlEntitiesRegex = /&(?:amp|lt|gt|quot|#39);/g;\nconst entityMap = new Map([\n ['&amp;', '&'],\n ['&lt;', '<'],\n ['&gt;', '>'],\n ['&quot;', '\"'],\n ['&#39;', '\\'']\n]);\n\n/**\n * Converts the HTML entities `&amp;`, `&lt;`, `&gt;`, `&quot;` and `&#39;`\n * in a string to their corresponding characters.\n *\n * @example\n * unescapeHtml('fred, barney, &amp; pebbles')\n * // => 'fred, barney, & pebbles'\n * @param str The string to unescape.\n * @returns Returns the unescaped string.\n */\n\nexport function unescapeHtml(str: string): string {\n return str.replace(htmlEntitiesRegex, (entity: string) => entityMap.get(entity)!);\n}\n","/**\n * Checks if `value` is an empty object, collection, map, or set.\n *\n * @example\n * isEmpty(null)\n * // => true\n *\n * isEmpty({})\n * // => true\n *\n * isEmpty(\"\")\n * // => true\n *\n * isEmpty([1, 2, 3])\n * // => false\n *\n * isEmpty('abc')\n * // => false\n *\n * isEmpty({ 'a': 1 })\n * // => false\n * @param value The value to check.\n * @returns Returns `true` if given vlaue is empty, else `false`.\n */\n\nexport function isEmpty(value: string | object | null | undefined): boolean {\n if (value === null || value === undefined) {\n return true;\n }\n\n if (typeof value === 'string' || Array.isArray(value)) {\n return value.length === 0;\n }\n\n if (value instanceof Map || value instanceof Set) {\n return value.size === 0;\n }\n\n if (typeof value === 'object') {\n return Object.keys(value).length === 0;\n }\n\n return false;\n}\n","/* eslint-disable complexity */\nimport type { PlainObject } from '@type/PlainObject.js';\n\nimport { isPlainObject } from './isPlainObject.js';\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * @example\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n * @param a The value to compare.\n * @param b The other value to compare.\n * @returns Returns `true` if the values are equivalent, else `false`.\n */\n\nexport function isEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n \n if (typeof a !== typeof b) return false;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return isSameArray(a, b);\n }\n\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.toString() === b.toString();\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n return isSameObject(a, b);\n }\n\n return false;\n}\n\nfunction isSameObject(a: PlainObject, b: PlainObject) {\n // check if the objects have the same keys\n const keys1 = Object.keys(a);\n const keys2 = Object.keys(b);\n if (!isEqual(keys1, keys2)) return false;\n\n // check if the values of each key in the objects are equal\n for (const key of keys1) {\n if (!isEqual(a[key], b[key])) return false;\n }\n\n // the objects are deeply equal\n return true;\n}\n\nfunction isSameArray(a: unknown[], b: unknown[]) {\n if (a.length !== b.length) return false;\n\n // check if the values of each element in the arrays are equal\n for (const [i, element] of a.entries()) {\n if (!isEqual(element, b[i])) return false;\n }\n\n return true;\n}\n","/**\n * Checks if given string is a valid URL\n *\n * @example\n * isUrl('https://google.com')\n * // => true\n * isUrl('google.com')\n * // => false\n * @param str The string to check.\n * @returns Returns `true` if given string is a valid URL, else `false`.\n */\n\nexport function isUrl(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return false;\n }\n}"],"mappings":"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","names":["difference","intersection","range","range","randomFloat","count","count","retries","timeout","camelCase","kebabCase","pascalCase","snakeCase","titleCase"]}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "moderndash",
3
- "version": "2.3.1",
3
+ "version": "3.1.0",
4
4
  "type": "module",
5
- "description": "A lodash inspired utility framework for ESM/Typescript/ESNext",
5
+ "description": "A Typescript-First utility library inspired by Lodash. Optimized for modern browsers.",
6
6
  "engines": {
7
7
  "node": ">=16.15",
8
8
  "npm": ">=8"
@@ -14,7 +14,7 @@
14
14
  "prepublishOnly": "npm run test && npm run build && cp '../README.md' './README.md' && cp '../LICENSE' './LICENSE'",
15
15
  "postpublish": "rm './README.md' && rm './LICENSE'",
16
16
  "test-dev": "vitest --ui",
17
- "test": "vitest run --coverage"
17
+ "test": "cross-env NODE_OPTIONS='--experimental-global-webcrypto' vitest run --coverage"
18
18
  },
19
19
  "repository": {
20
20
  "type": "git",
@@ -44,14 +44,16 @@
44
44
  "types": "./dist/index.d.ts",
45
45
  "import": "./dist/index.js",
46
46
  "require": "./dist/index.cjs"
47
- }
47
+ },
48
+ "./package.json": "./package.json"
48
49
  },
49
50
  "files": [
50
51
  "dist"
51
52
  ],
52
53
  "homepage": "https://moderndash.io",
53
54
  "devDependencies": {
54
- "tsup": "6.6.3",
55
- "ctix": "1.8.2"
55
+ "tsup": "6.7.0",
56
+ "ctix": "1.8.2",
57
+ "cross-env": "7.0.3"
56
58
  }
57
59
  }