@w3ux/utils 2.2.3 → 2.3.1

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/index.cjs CHANGED
@@ -75,7 +75,7 @@ var minDecimalPlaces = (val, minDecimals) => {
75
75
  const missingDecimals = minDecimals - fractionalPart.length;
76
76
  const formattedWhole = retainCommas ? Intl.NumberFormat("en-US").format(whole) : whole.toString();
77
77
  return missingDecimals > 0 ? `${formattedWhole}.${fractionalPart}${"0".repeat(missingDecimals)}` : `${formattedWhole}.${fractionalPart}`;
78
- } catch (e) {
78
+ } catch {
79
79
  return "0";
80
80
  }
81
81
  };
@@ -97,7 +97,7 @@ var camelize = (str) => {
97
97
  for (let i = 0; i < inp?.length; i++) {
98
98
  const currString = inp[i];
99
99
  let tmpStr = currString.toLowerCase();
100
- if (i != 0) {
100
+ if (i !== 0) {
101
101
  tmpStr = tmpStr.slice(0, 1).toUpperCase() + tmpStr.slice(1, tmpStr.length);
102
102
  }
103
103
  result += tmpStr;
@@ -180,14 +180,14 @@ var appendOr = (condition, value, fallback) => condition ? ` ${value}` : ` ${fal
180
180
  var formatAccountSs58 = (address, ss58) => {
181
181
  try {
182
182
  return (0, import_utils.encodeAddress)(address, ss58);
183
- } catch (e) {
183
+ } catch {
184
184
  return null;
185
185
  }
186
186
  };
187
187
  var tryFormatSs58 = (address, ss58) => {
188
188
  try {
189
189
  return (0, import_utils.encodeAddress)(address, ss58);
190
- } catch (e) {
190
+ } catch {
191
191
  return address;
192
192
  }
193
193
  };
@@ -229,7 +229,7 @@ var planckToUnit = (val, units) => {
229
229
  const fractionalPart = bigIntVal % divisor;
230
230
  const fractionalStr = units > 0 ? `.${fractionalPart.toString().padStart(units, "0")}` : ``;
231
231
  return `${integerPart}${fractionalStr}`;
232
- } catch (e) {
232
+ } catch {
233
233
  return "0";
234
234
  }
235
235
  };
@@ -249,7 +249,7 @@ var unitToPlanck = (val, units) => {
249
249
  bigIntValue += fractionalValue;
250
250
  }
251
251
  return bigIntValue;
252
- } catch (e) {
252
+ } catch {
253
253
  return BigInt(0);
254
254
  }
255
255
  };
@@ -277,7 +277,7 @@ var isValidAddress = (address) => {
277
277
  try {
278
278
  (0, import_utils2.decodeAddress)(address);
279
279
  return true;
280
- } catch (e) {
280
+ } catch {
281
281
  return false;
282
282
  }
283
283
  };
@@ -397,7 +397,7 @@ var makeCancelable = (promise) => {
397
397
  }
398
398
  };
399
399
  };
400
- var unimplemented = ({ ...props }) => {
400
+ var unimplemented = (_props) => {
401
401
  };
402
402
  var mergeDeep = (target, ...sources) => {
403
403
  if (!sources.length) {
package/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/base.ts","../src/convert.ts","../src/unit.ts"],"sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nexport * from './base'\nexport * from './convert'\nexport * from './unit'\n","/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { encodeAddress } from 'dedot/utils'\n\n/**\n * Ensures a number has at least the specified number of decimal places, retaining commas in the output if they are present in the input.\n *\n * @function minDecimalPlaces\n * @param {string | number | BigInt} val - The input number, which can be a `string` with or without commas, a `number`, or a `BigInt`.\n * @param {number} minDecimals - The minimum number of decimal places to enforce.\n * @returns {string} The formatted number as a string, padded with zeros if needed to meet `minDecimals`, retaining commas if originally provided.\n * If `val` is invalid, returns \"0\".\n * @example\n * // Pads \"1,234.5\" to have at least 3 decimal places, with commas\n * minDecimalPlaces(\"1,234.5\", 3); // returns \"1,234.500\"\n *\n * // Returns \"1234.56\" unchanged\n * minDecimalPlaces(1234.56, 2); // returns \"1234.56\"\n *\n * // Pads BigInt 1234 with 2 decimals\n * minDecimalPlaces(BigInt(1234), 2); // returns \"1234.00\"\n */\nexport const minDecimalPlaces = (\n val: string | number | bigint,\n minDecimals: number\n): string => {\n try {\n // Determine if we should retain commas based on original input type\n const retainCommas = typeof val === 'string' && val.includes(',')\n\n // Convert `val` to a plain string for processing\n const strVal =\n typeof val === 'string' ? val.replace(/,/g, '') : val.toString()\n\n // Separate integer and decimal parts\n const [integerPart, fractionalPart = ''] = strVal.split('.')\n\n // Parse the integer part as a BigInt\n const whole = BigInt(integerPart || '0')\n\n // Calculate missing decimal places\n const missingDecimals = minDecimals - fractionalPart.length\n\n // Format the integer part back with commas only if the input had commas\n const formattedWhole = retainCommas\n ? Intl.NumberFormat('en-US').format(whole)\n : whole.toString()\n\n // If missing decimals are needed, pad with zeros; otherwise, return the original value\n return missingDecimals > 0\n ? `${formattedWhole}.${fractionalPart}${'0'.repeat(missingDecimals)}`\n : `${formattedWhole}.${fractionalPart}`\n } catch (e) {\n // The provided value is not a valid number, return \"0\".\n return '0'\n }\n}\n\n/**\n * @name camelize\n * @summary Converts a string of text to camelCase.\n */\nexport const camelize = (str: string) => {\n const convertToString = (string: string) => {\n if (string) {\n if (typeof string === 'string') {\n return string\n }\n return String(string)\n }\n return ''\n }\n\n const toWords = (inp: string) =>\n convertToString(inp).match(\n /[A-Z\\xC0-\\xD6\\xD8-\\xDE]?[a-z\\xDF-\\xF6\\xF8-\\xFF]+|[A-Z\\xC0-\\xD6\\xD8-\\xDE]+(?![a-z\\xDF-\\xF6\\xF8-\\xFF])|\\d+/g\n )\n\n const simpleCamelCase = (inp: string[]) => {\n let result = ''\n for (let i = 0; i < inp?.length; i++) {\n const currString = inp[i]\n let tmpStr = currString.toLowerCase()\n if (i != 0) {\n tmpStr =\n tmpStr.slice(0, 1).toUpperCase() + tmpStr.slice(1, tmpStr.length)\n }\n result += tmpStr\n }\n return result\n }\n\n const w = toWords(str)?.map((a) => a.toLowerCase())\n return simpleCamelCase(w || [])\n}\n\n/**\n * @name ellipsisFn\n * @summary Receives an address and creates ellipsis on the given string, based on parameters.\n * @param str - The string to apply the ellipsis on\n * @param amount - The amount of characters that the ellipsis will be\n * @param position - where the ellipsis will apply; if center the amount of character is the\n * same for beginning and end; if \"start\" or \"end\" then its only once the amount; defaults to \"start\"\n */\nexport const ellipsisFn = (\n str: string,\n amount = 6,\n position: 'start' | 'end' | 'center' = 'center'\n) => {\n const half = str.length / 2\n\n // having an amount less than 4 is a bit extreme so we default there\n if (amount <= 4) {\n if (position === 'center') {\n return str.slice(0, 4) + '...' + str.slice(-4)\n }\n if (position === 'end') {\n return str.slice(0, 4) + '...'\n }\n return '...' + str.slice(-4)\n }\n // if the amount requested is in a \"logical\" amount - meaning that it can display the address\n // without repeating the same information twice - then go for it;\n if (position === 'center') {\n return amount >= (str.length - 2) / 2\n ? str.slice(0, half - 3) + '...' + str.slice(-(half - 3))\n : str.slice(0, amount) + '...' + str.slice(-amount)\n }\n // else, the user has been mistaskenly extreme, so just show the maximum possible amount\n if (amount >= str.length) {\n if (position === 'end') {\n return str.slice(0, str.length - 3) + '...'\n }\n return '...' + str.slice(-(str.length - 3))\n } else {\n if (position === 'end') {\n return str.slice(0, amount) + '...'\n }\n return '...' + str.slice(amount)\n }\n}\n\n/**\n * @name pageFromUri\n * @summary Use url variables to load the default components upon the first page visit.\n */\nexport const pageFromUri = (pathname: string, fallback: string) => {\n const lastUriItem = pathname.substring(pathname.lastIndexOf('/') + 1)\n const page = lastUriItem.trim() === '' ? fallback : lastUriItem\n return page.trim()\n}\n\n/**\n * @name rmCommas\n * @summary Removes the commas from a string.\n */\nexport const rmCommas = (val: string): string => val.replace(/,/g, '')\n\n/**\n * @name rmDecimals\n * @summary Removes the decimal point and decimals from a string.\n */\nexport const rmDecimals = (str: string) => str.split('.')[0]\n\n/**\n * @name shuffle\n * @summary Shuffle a set of objects.\n */\nexport const shuffle = <T>(array: T[]) => {\n let currentIndex = array.length\n let randomIndex\n while (currentIndex !== 0) {\n randomIndex = Math.floor(Math.random() * currentIndex)\n currentIndex--\n ;[array[currentIndex], array[randomIndex]] = [\n array[randomIndex],\n array[currentIndex],\n ]\n }\n return array\n}\n\n/**\n * @name withTimeout\n * @summary Timeout a promise after a specified number of milliseconds.\n */\nexport const withTimeout = (\n ms: number,\n promise: Promise<unknown>,\n options?: {\n onTimeout?: () => void\n }\n) => {\n const timeout = new Promise((resolve) =>\n setTimeout(async () => {\n if (typeof options?.onTimeout === 'function') {\n options.onTimeout()\n }\n resolve(undefined)\n }, ms)\n )\n return Promise.race([promise, timeout])\n}\n\n/**\n * @name withTimeoutThrow\n * @summary Timeout a promise after a specified number of milliseconds by throwing an error\n */\nexport const withTimeoutThrow = <T>(\n ms: number,\n promise: Promise<T>,\n options?: {\n onTimeout?: () => void\n }\n) => {\n const timeout = new Promise((reject) =>\n setTimeout(async () => {\n if (typeof options?.onTimeout === 'function') {\n options.onTimeout()\n }\n reject('Function timeout')\n }, ms)\n )\n return Promise.race([promise, timeout])\n}\n\n/**\n * @name appendOrEmpty\n * @summary Returns ` value` if a condition is truthy, or an empty string otherwise.\n */\nexport const appendOrEmpty = (\n condition: boolean | string | undefined,\n value: string\n) => (condition ? ` ${value}` : '')\n\n/**\n * @name appendOr\n * @summary Returns ` value` if condition is truthy, or ` fallback` otherwise.\n */\nexport const appendOr = (\n condition: boolean | string | undefined,\n value: string,\n fallback: string\n) => (condition ? ` ${value}` : ` ${fallback}`)\n\n/**\n * @name formatAccountSs58\n * @summary Formats an address with the supplied ss58 prefix, or returns null if invalid.\n */\nexport const formatAccountSs58 = (\n address: string,\n ss58: number\n): string | null => {\n try {\n return encodeAddress(address, ss58)\n } catch (e) {\n return null\n }\n}\n\n/**\n * @name tryFormatSs58\n * @summary Formats an address with the supplied ss58 prefix, or returns the original address if\n * invalid.\n */\nexport const tryFormatSs58 = (address: string, ss58: number): string => {\n try {\n return encodeAddress(address, ss58)\n } catch (e) {\n return address\n }\n}\n\n/**\n * @name removeHexPrefix\n * @summary Takes a string str as input and returns a new string with the \"0x\" prefix removed if it\n * exists at the beginning of the input string.\n */\nexport const removeHexPrefix = (str: string): string => str.replace(/^0x/, '')\n\n// Check if 2 sets contain the same elements.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const eqSet = (xs: Set<any>, ys: Set<any>) =>\n xs.size === ys.size && [...xs].every((x) => ys.has(x))\n\n// Check if one set contains all the elements of another set.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isSuperset = (set: Set<any>, subset: Set<any>) => {\n for (const elem of subset) {\n if (!set.has(elem)) {\n return false\n }\n }\n return true\n}\n\n/**\n * Finds the maximum value among a list of BigInt values.\n *\n * @function maxBigInt\n * @param {...bigint} values - A list of BigInt values to compare.\n * @returns {bigint} The largest BigInt value in the provided list.\n * @example\n * // Returns the maximum BigInt value\n * maxBigInt(10n, 50n, 30n, 100n, 20n); // 100n\n */\nexport const maxBigInt = (...values: bigint[]): bigint =>\n values.reduce((max, current) => (current > max ? current : max))\n\n/**\n * Finds the minimum value among a list of BigInt values.\n *\n * @function minBigInt\n * @param {...bigint} values - A list of BigInt values to compare.\n * @returns {bigint} The smallest BigInt value in the provided list.\n * @example\n * // Returns the minimum BigInt value\n * minBigInt(10n, 50n, 30n, 100n, 20n); // 10n\n */\nexport const minBigInt = (...values: bigint[]): bigint =>\n values.reduce((min, current) => (current < min ? current : min))\n","// /* @license Copyright 2024 w3ux authors & contributors\n// SPDX-License-Identifier: GPL-3.0-only */\n\n/**\n * Concatenates multiple Uint8Array instances into a single Uint8Array.\n *\n * @param {Uint8Array[]} u8as - An array of Uint8Array instances to concatenate.\n * @returns {Uint8Array} A new Uint8Array containing all the input arrays concatenated.\n */\nexport const u8aConcat = (...u8as: Uint8Array[]): Uint8Array => {\n // Calculate the total length of the resulting Uint8Array\n const totalLength = u8as.reduce((sum, u8a) => sum + u8a.length, 0)\n\n // Create a new Uint8Array with the total length\n const result = new Uint8Array(totalLength)\n\n let offset = 0 // Initialize the offset for placing elements\n for (const u8a of u8as) {\n result.set(u8a, offset) // Set the current Uint8Array at the current offset\n offset += u8a.length // Update the offset for the next Uint8Array\n }\n\n return result\n}\n","/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { decodeAddress } from 'dedot/utils'\nimport type { RefObject } from 'react'\nimport { rmCommas, rmDecimals } from './base'\nimport type { AnyObject } from './types'\n\n/**\n * Converts an on-chain balance value from planck to a decimal value in token units.\n *\n * @function planckToUnit\n * @param {number | BigInt | string} val - The balance value in planck. Accepts a `number`, `BigInt`, or `string`.\n * @param {number} units - The number of decimal places in the token unit (10^units planck per 1 token).\n * @returns {string} The equivalent token unit value as a decimal string.\n * @example\n * // Convert 1500000000000 planck to tokens with 12 decimal places\n * planckToUnit(\"1500000000000\", 12); // returns \"1.5\"\n */\nexport const planckToUnit = (\n val: number | bigint | string,\n units: number\n): string => {\n try {\n // Ensure `units` is a positive integer.\n units = Math.max(Math.round(units), 0)\n\n // Convert `val` to BigInt based on its type\n const bigIntVal =\n typeof val === 'bigint'\n ? val\n : BigInt(\n typeof val === 'number'\n ? Math.floor(val).toString()\n : rmDecimals(rmCommas(val))\n )\n\n const divisor = units === 0 ? 1n : BigInt(10) ** BigInt(units)\n\n // Integer division and remainder for the fractional part\n const integerPart = bigIntVal / divisor\n const fractionalPart = bigIntVal % divisor\n\n // Format fractional part with leading zeros to maintain `units` decimal places\n const fractionalStr =\n units > 0 ? `.${fractionalPart.toString().padStart(units, '0')}` : ``\n\n // Combine integer and fractional parts as a decimal string\n return `${integerPart}${fractionalStr}`\n } catch (e) {\n return '0'\n }\n}\n\n/**\n * Converts a token unit value to an integer value in planck.\n *\n * @function unitToPlanck\n * @param {string | number | BigInt} val - The token unit value to convert. Accepts a string, number, or BigInt.\n * @param {number} units - The number of decimal places for conversion (10^units planck per 1 token).\n * @returns {BigInt} The equivalent value in planck as a BigInt.\n * @example\n * // Convert \"1.5\" tokens to planck with 12 decimal places\n * unitToPlanck(\"1.5\", 12); // returns BigInt(\"1500000000000\")\n */\nexport const unitToPlanck = (\n val: string | number | bigint,\n units: number\n): bigint => {\n try {\n // Ensure `units` is a positive integer.\n units = Math.max(Math.round(units), 0)\n\n // Convert `val` to a string; if empty or invalid, default to \"0\"\n const strVal =\n (typeof val === 'string' ? rmCommas(val) : val.toString()) || '0'\n\n // Split into integer and fractional parts\n const [integerPart, fractionalPart = ''] = strVal.split('.')\n\n // Process the integer part by converting to BigInt and scaling it to the given units\n let bigIntValue = BigInt(integerPart) * BigInt(10) ** BigInt(units)\n\n // Process the fractional part if it exists\n if (fractionalPart) {\n let fractionalValue: bigint\n\n if (fractionalPart.length > units) {\n // If fractional part exceeds units, truncate it\n fractionalValue = BigInt(fractionalPart.slice(0, units))\n } else {\n // Otherwise, pad the fractional part to match units\n fractionalValue = BigInt(fractionalPart.padEnd(units, '0'))\n }\n\n bigIntValue += fractionalValue\n }\n\n return bigIntValue\n } catch (e) {\n return BigInt(0)\n }\n}\n\n/**\n * @name remToUnit\n * @summary Converts a rem string to a number.\n */\nexport const remToUnit = (rem: string) =>\n Number(rem.slice(0, rem.length - 3)) *\n parseFloat(getComputedStyle(document.documentElement).fontSize)\n\n/**\n * @name capitalizeFirstLetter\n * @summary Capitalize the first letter of a string.\n */\nexport const capitalizeFirstLetter = (string: string) =>\n string.charAt(0).toUpperCase() + string.slice(1)\n\n/**\n * @name snakeToCamel\n * @summary converts a string from snake / kebab-case to camel-case.\n */\nexport const snakeToCamel = (str: string) =>\n str\n .toLowerCase()\n .replace(/([-_][a-z])/g, (group) =>\n group.toUpperCase().replace('-', '').replace('_', '')\n )\n\n/**\n * @name setStateWithRef\n * @summary Synchronize React state and its reference with the provided value.\n */\nexport const setStateWithRef = <T>(\n value: T,\n setState: (_state: T) => void,\n ref: RefObject<T>\n): void => {\n setState(value)\n ref.current = value\n}\n\n/**\n * @name localStorageOrDefault\n * @summary Retrieve the local stroage value with the key, return defult value if it is not\n * found.\n */\nexport const localStorageOrDefault = <T>(\n key: string,\n _default: T,\n parse = false\n): T | string => {\n const val: string | null = localStorage.getItem(key)\n\n if (val === null) {\n return _default\n }\n\n if (parse) {\n return JSON.parse(val) as T\n }\n return val\n}\n\n/**\n * @name isValidAddress\n * @summary Return whether an address is valid Substrate address.\n */\nexport const isValidAddress = (address: string): boolean => {\n try {\n decodeAddress(address)\n return true\n } catch (e) {\n return false\n }\n}\n\n/**\n * @name extractUrlValue\n * @summary Extracts a URL value from a URL string.\n */\nexport const extractUrlValue = (key: string, url?: string) => {\n if (typeof url === 'undefined') {\n url = window.location.href\n }\n const match = url.match(`[?&]${key}=([^&]+)`)\n return match ? match[1] : null\n}\n\n/**\n * @name varToUrlHash\n * @summary Puts a variable into the URL hash as a param.\n * @description\n * Since url variables are added to the hash and are not treated as URL params, the params are split\n * and parsed into a `URLSearchParams`.\n */\nexport const varToUrlHash = (\n key: string,\n val: string,\n addIfMissing: boolean\n) => {\n const hash = window.location.hash\n const [page, params] = hash.split('?')\n const searchParams = new URLSearchParams(params)\n\n if (searchParams.get(key) === null && !addIfMissing) {\n return\n }\n searchParams.set(key, val)\n window.location.hash = `${page}?${searchParams.toString()}`\n}\n\n/**\n * @name removeVarFromUrlHash\n * @summary\n * Removes a variable `key` from the URL hash if it exists. Removes dangling `?` if no URL variables\n * exist.\n */\nexport const removeVarFromUrlHash = (key: string) => {\n const hash = window.location.hash\n const [page, params] = hash.split('?')\n const searchParams = new URLSearchParams(params)\n if (searchParams.get(key) === null) {\n return\n }\n searchParams.delete(key)\n const paramsAsStr = searchParams.toString()\n window.location.hash = `${page}${paramsAsStr ? `?${paramsAsStr}` : ``}`\n}\n\n/**\n * @name sortWithNull\n * @summary Sorts an array with nulls last.\n */\nexport const sortWithNull =\n (ascending: boolean) => (a: unknown, b: unknown) => {\n // if both items are undefined, treat them as equal\n if (typeof a === 'undefined' && typeof b === 'undefined') {\n return 0\n }\n // if either item is undefined, sort it last\n if (typeof a === 'undefined' || typeof b === 'undefined') {\n return typeof a === 'undefined' ? 1 : -1\n }\n // equal items sort equally\n if (a === b) {\n return 0\n }\n // nulls sort after anything else\n if (a === null) {\n return 1\n }\n if (b === null) {\n return -1\n }\n // otherwise, if we're ascending, lowest sorts first\n if (ascending) {\n return a < b ? -1 : 1\n }\n // if descending, highest sorts first\n return a < b ? 1 : -1\n }\n\n/**\n * @name applyWidthAsPadding\n * @summary Applies width of subject to paddingRight of container.\n */\nexport const applyWidthAsPadding = (\n subjectRef: RefObject<HTMLDivElement | null>,\n containerRef: RefObject<HTMLDivElement | null>\n) => {\n if (containerRef.current && subjectRef.current) {\n containerRef.current.style.paddingRight = `${\n subjectRef.current.offsetWidth + remToUnit('1rem')\n }px`\n }\n}\n\n/**\n * @name unescape\n * @summary Replaces \\” with “\n */\nexport const unescape = (val: string) => val.replace(/\\\\\"/g, '\"')\n\n/**\n * @name inChrome\n * @summary Whether the application is rendering in Chrome.\n */\nexport const inChrome = () => {\n const isChromium = (window as Window & { chrome?: boolean })?.chrome || null\n const winNav = (window as Window)?.navigator || null\n const isOpera =\n typeof (window as Window & { opr?: boolean })?.opr !== 'undefined'\n const isIEedge = winNav?.userAgent.indexOf('Edg') > -1 || false\n const isIOSChrome = winNav?.userAgent.match('CriOS') || false\n\n if (isIOSChrome) {\n return true\n }\n if (\n isChromium !== null &&\n typeof isChromium !== 'undefined' &&\n isOpera === false &&\n isIEedge === false\n ) {\n return true\n }\n return false\n}\n\n/**\n * @name addedTo\n * @summary Given 2 objects and some keys, return items in the fresh object that do not exist in the\n * stale object by matching the given common key values of both objects.\n */\nexport const addedTo = (\n fresh: AnyObject[],\n stale: AnyObject[],\n keys: string[]\n): AnyObject[] =>\n typeof fresh !== 'object' || typeof stale !== 'object' || !keys.length\n ? []\n : fresh.filter(\n (freshItem) =>\n !stale.find((staleItem) =>\n keys.every((key) =>\n !(key in staleItem) || !(key in freshItem)\n ? false\n : staleItem[key] === freshItem[key]\n )\n )\n )\n\n/**\n * @name removedFrom\n * @summary Given 2 objects and some keys, return items in the stale object that do not exist in the\n * fresh object by matching the given common key values of both objects.\n */\nexport const removedFrom = (\n fresh: AnyObject[],\n stale: AnyObject[],\n keys: string[]\n): AnyObject[] =>\n typeof fresh !== 'object' || typeof stale !== 'object' || !keys.length\n ? []\n : stale.filter(\n (staleItem) =>\n !fresh.find((freshItem) =>\n keys.every((key) =>\n !(key in staleItem) || !(key in freshItem)\n ? false\n : freshItem[key] === staleItem[key]\n )\n )\n )\n\n/**\n * @name matchedProperties\n * @summary Given 2 objects and some keys, return items in object 1 that also exist in object 2 by\n * matching the given common key values of both objects.\n */\nexport const matchedProperties = (\n objX: AnyObject[],\n objY: AnyObject[],\n keys: string[]\n): AnyObject[] =>\n typeof objX !== 'object' || typeof objY !== 'object' || !keys.length\n ? []\n : objY.filter((x) =>\n objX.find((y) =>\n keys.every((key) =>\n !(key in x) || !(key in y) ? false : y[key] === x[key]\n )\n )\n )\n\n/**\n * @name isValidHttpUrl\n * @summary Give a string, return whether it is a valid http URL.\n * @param string - The string to check.\n */\nexport const isValidHttpUrl = (string: string) => {\n let url: URL\n try {\n url = new URL(string)\n } catch (_) {\n return false\n }\n return url.protocol === 'http:' || url.protocol === 'https:'\n}\n\n/**\n * @name makeCancelable\n * @summary Makes a promise cancellable.\n * @param promise - The promise to make cancellable.\n */\nexport const makeCancelable = (promise: Promise<AnyObject>) => {\n let hasCanceled = false\n\n const wrappedPromise = new Promise((resolve, reject) => {\n promise.then((val) =>\n hasCanceled ? reject(Error('Cancelled')) : resolve(val)\n )\n promise.catch((error) =>\n hasCanceled ? reject(Error('Cancelled')) : reject(error)\n )\n })\n\n return {\n promise: wrappedPromise,\n cancel: () => {\n hasCanceled = true\n },\n }\n}\n\n/**\n * @name unimplemented\n * @summary A placeholder function to signal a deliberate unimplementation.\n * Consumes an arbitrary number of props.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const unimplemented = ({ ...props }) => {\n /* unimplemented */\n}\n\n/**\n * Deep merge two objects.\n * @param target\n * @param ...sources\n */\n\nexport const mergeDeep = (\n target: AnyObject,\n ...sources: AnyObject[]\n): AnyObject => {\n if (!sources.length) {\n return target\n }\n\n const isObject = (item: AnyObject) =>\n item && typeof item === 'object' && !Array.isArray(item)\n const source = sources.shift()\n\n if (isObject(target) && isObject(source)) {\n for (const key in source) {\n if (isObject(source[key])) {\n if (!target[key]) {\n Object.assign(target, { [key]: {} })\n }\n mergeDeep(target[key], source[key])\n } else {\n Object.assign(target, { [key]: source[key] })\n }\n }\n }\n return mergeDeep(target, ...sources)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGA,mBAA8B;AAoBvB,IAAM,mBAAmB,CAC9B,KACA,gBACW;AACX,MAAI;AAEF,UAAM,eAAe,OAAO,QAAQ,YAAY,IAAI,SAAS,GAAG;AAGhE,UAAM,SACJ,OAAO,QAAQ,WAAW,IAAI,QAAQ,MAAM,EAAE,IAAI,IAAI,SAAS;AAGjE,UAAM,CAAC,aAAa,iBAAiB,EAAE,IAAI,OAAO,MAAM,GAAG;AAG3D,UAAM,QAAQ,OAAO,eAAe,GAAG;AAGvC,UAAM,kBAAkB,cAAc,eAAe;AAGrD,UAAM,iBAAiB,eACnB,KAAK,aAAa,OAAO,EAAE,OAAO,KAAK,IACvC,MAAM,SAAS;AAGnB,WAAO,kBAAkB,IACrB,GAAG,cAAc,IAAI,cAAc,GAAG,IAAI,OAAO,eAAe,CAAC,KACjE,GAAG,cAAc,IAAI,cAAc;AAAA,EACzC,SAAS,GAAG;AAEV,WAAO;AAAA,EACT;AACF;AAMO,IAAM,WAAW,CAAC,QAAgB;AACvC,QAAM,kBAAkB,CAAC,WAAmB;AAC1C,QAAI,QAAQ;AACV,UAAI,OAAO,WAAW,UAAU;AAC9B,eAAO;AAAA,MACT;AACA,aAAO,OAAO,MAAM;AAAA,IACtB;AACA,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,CAAC,QACf,gBAAgB,GAAG,EAAE;AAAA,IACnB;AAAA,EACF;AAEF,QAAM,kBAAkB,CAAC,QAAkB;AACzC,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,aAAa,IAAI,CAAC;AACxB,UAAI,SAAS,WAAW,YAAY;AACpC,UAAI,KAAK,GAAG;AACV,iBACE,OAAO,MAAM,GAAG,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,GAAG,OAAO,MAAM;AAAA,MACpE;AACA,gBAAU;AAAA,IACZ;AACA,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,QAAQ,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAClD,SAAO,gBAAgB,KAAK,CAAC,CAAC;AAChC;AAUO,IAAM,aAAa,CACxB,KACA,SAAS,GACT,WAAuC,aACpC;AACH,QAAM,OAAO,IAAI,SAAS;AAG1B,MAAI,UAAU,GAAG;AACf,QAAI,aAAa,UAAU;AACzB,aAAO,IAAI,MAAM,GAAG,CAAC,IAAI,QAAQ,IAAI,MAAM,EAAE;AAAA,IAC/C;AACA,QAAI,aAAa,OAAO;AACtB,aAAO,IAAI,MAAM,GAAG,CAAC,IAAI;AAAA,IAC3B;AACA,WAAO,QAAQ,IAAI,MAAM,EAAE;AAAA,EAC7B;AAGA,MAAI,aAAa,UAAU;AACzB,WAAO,WAAW,IAAI,SAAS,KAAK,IAChC,IAAI,MAAM,GAAG,OAAO,CAAC,IAAI,QAAQ,IAAI,MAAM,EAAE,OAAO,EAAE,IACtD,IAAI,MAAM,GAAG,MAAM,IAAI,QAAQ,IAAI,MAAM,CAAC,MAAM;AAAA,EACtD;AAEA,MAAI,UAAU,IAAI,QAAQ;AACxB,QAAI,aAAa,OAAO;AACtB,aAAO,IAAI,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI;AAAA,IACxC;AACA,WAAO,QAAQ,IAAI,MAAM,EAAE,IAAI,SAAS,EAAE;AAAA,EAC5C,OAAO;AACL,QAAI,aAAa,OAAO;AACtB,aAAO,IAAI,MAAM,GAAG,MAAM,IAAI;AAAA,IAChC;AACA,WAAO,QAAQ,IAAI,MAAM,MAAM;AAAA,EACjC;AACF;AAMO,IAAM,cAAc,CAAC,UAAkB,aAAqB;AACjE,QAAM,cAAc,SAAS,UAAU,SAAS,YAAY,GAAG,IAAI,CAAC;AACpE,QAAM,OAAO,YAAY,KAAK,MAAM,KAAK,WAAW;AACpD,SAAO,KAAK,KAAK;AACnB;AAMO,IAAM,WAAW,CAAC,QAAwB,IAAI,QAAQ,MAAM,EAAE;AAM9D,IAAM,aAAa,CAAC,QAAgB,IAAI,MAAM,GAAG,EAAE,CAAC;AAMpD,IAAM,UAAU,CAAI,UAAe;AACxC,MAAI,eAAe,MAAM;AACzB,MAAI;AACJ,SAAO,iBAAiB,GAAG;AACzB,kBAAc,KAAK,MAAM,KAAK,OAAO,IAAI,YAAY;AACrD;AACC,KAAC,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC,IAAI;AAAA,MAC3C,MAAM,WAAW;AAAA,MACjB,MAAM,YAAY;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;AAMO,IAAM,cAAc,CACzB,IACA,SACA,YAGG;AACH,QAAM,UAAU,IAAI;AAAA,IAAQ,CAAC,YAC3B,WAAW,YAAY;AACrB,UAAI,OAAO,SAAS,cAAc,YAAY;AAC5C,gBAAQ,UAAU;AAAA,MACpB;AACA,cAAQ,MAAS;AAAA,IACnB,GAAG,EAAE;AAAA,EACP;AACA,SAAO,QAAQ,KAAK,CAAC,SAAS,OAAO,CAAC;AACxC;AAMO,IAAM,mBAAmB,CAC9B,IACA,SACA,YAGG;AACH,QAAM,UAAU,IAAI;AAAA,IAAQ,CAAC,WAC3B,WAAW,YAAY;AACrB,UAAI,OAAO,SAAS,cAAc,YAAY;AAC5C,gBAAQ,UAAU;AAAA,MACpB;AACA,aAAO,kBAAkB;AAAA,IAC3B,GAAG,EAAE;AAAA,EACP;AACA,SAAO,QAAQ,KAAK,CAAC,SAAS,OAAO,CAAC;AACxC;AAMO,IAAM,gBAAgB,CAC3B,WACA,UACI,YAAY,IAAI,KAAK,KAAK;AAMzB,IAAM,WAAW,CACtB,WACA,OACA,aACI,YAAY,IAAI,KAAK,KAAK,IAAI,QAAQ;AAMrC,IAAM,oBAAoB,CAC/B,SACA,SACkB;AAClB,MAAI;AACF,eAAO,4BAAc,SAAS,IAAI;AAAA,EACpC,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AACF;AAOO,IAAM,gBAAgB,CAAC,SAAiB,SAAyB;AACtE,MAAI;AACF,eAAO,4BAAc,SAAS,IAAI;AAAA,EACpC,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AACF;AAOO,IAAM,kBAAkB,CAAC,QAAwB,IAAI,QAAQ,OAAO,EAAE;AAItE,IAAM,QAAQ,CAAC,IAAc,OAClC,GAAG,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAIhD,IAAM,aAAa,CAAC,KAAe,WAAqB;AAC7D,aAAW,QAAQ,QAAQ;AACzB,QAAI,CAAC,IAAI,IAAI,IAAI,GAAG;AAClB,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAYO,IAAM,YAAY,IAAI,WAC3B,OAAO,OAAO,CAAC,KAAK,YAAa,UAAU,MAAM,UAAU,GAAI;AAY1D,IAAM,YAAY,IAAI,WAC3B,OAAO,OAAO,CAAC,KAAK,YAAa,UAAU,MAAM,UAAU,GAAI;;;ACxT1D,IAAM,YAAY,IAAI,SAAmC;AAE9D,QAAM,cAAc,KAAK,OAAO,CAAC,KAAK,QAAQ,MAAM,IAAI,QAAQ,CAAC;AAGjE,QAAM,SAAS,IAAI,WAAW,WAAW;AAEzC,MAAI,SAAS;AACb,aAAW,OAAO,MAAM;AACtB,WAAO,IAAI,KAAK,MAAM;AACtB,cAAU,IAAI;AAAA,EAChB;AAEA,SAAO;AACT;;;ACpBA,IAAAA,gBAA8B;AAgBvB,IAAM,eAAe,CAC1B,KACA,UACW;AACX,MAAI;AAEF,YAAQ,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,CAAC;AAGrC,UAAM,YACJ,OAAO,QAAQ,WACX,MACA;AAAA,MACE,OAAO,QAAQ,WACX,KAAK,MAAM,GAAG,EAAE,SAAS,IACzB,WAAW,SAAS,GAAG,CAAC;AAAA,IAC9B;AAEN,UAAM,UAAU,UAAU,IAAI,KAAK,OAAO,EAAE,KAAK,OAAO,KAAK;AAG7D,UAAM,cAAc,YAAY;AAChC,UAAM,iBAAiB,YAAY;AAGnC,UAAM,gBACJ,QAAQ,IAAI,IAAI,eAAe,SAAS,EAAE,SAAS,OAAO,GAAG,CAAC,KAAK;AAGrE,WAAO,GAAG,WAAW,GAAG,aAAa;AAAA,EACvC,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AACF;AAaO,IAAM,eAAe,CAC1B,KACA,UACW;AACX,MAAI;AAEF,YAAQ,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,CAAC;AAGrC,UAAM,UACH,OAAO,QAAQ,WAAW,SAAS,GAAG,IAAI,IAAI,SAAS,MAAM;AAGhE,UAAM,CAAC,aAAa,iBAAiB,EAAE,IAAI,OAAO,MAAM,GAAG;AAG3D,QAAI,cAAc,OAAO,WAAW,IAAI,OAAO,EAAE,KAAK,OAAO,KAAK;AAGlE,QAAI,gBAAgB;AAClB,UAAI;AAEJ,UAAI,eAAe,SAAS,OAAO;AAEjC,0BAAkB,OAAO,eAAe,MAAM,GAAG,KAAK,CAAC;AAAA,MACzD,OAAO;AAEL,0BAAkB,OAAO,eAAe,OAAO,OAAO,GAAG,CAAC;AAAA,MAC5D;AAEA,qBAAe;AAAA,IACjB;AAEA,WAAO;AAAA,EACT,SAAS,GAAG;AACV,WAAO,OAAO,CAAC;AAAA,EACjB;AACF;AAMO,IAAM,YAAY,CAAC,QACxB,OAAO,IAAI,MAAM,GAAG,IAAI,SAAS,CAAC,CAAC,IACnC,WAAW,iBAAiB,SAAS,eAAe,EAAE,QAAQ;AAMzD,IAAM,wBAAwB,CAAC,WACpC,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC;AAM1C,IAAM,eAAe,CAAC,QAC3B,IACG,YAAY,EACZ;AAAA,EAAQ;AAAA,EAAgB,CAAC,UACxB,MAAM,YAAY,EAAE,QAAQ,KAAK,EAAE,EAAE,QAAQ,KAAK,EAAE;AACtD;AAMG,IAAM,kBAAkB,CAC7B,OACA,UACA,QACS;AACT,WAAS,KAAK;AACd,MAAI,UAAU;AAChB;AAOO,IAAM,wBAAwB,CACnC,KACA,UACA,QAAQ,UACO;AACf,QAAM,MAAqB,aAAa,QAAQ,GAAG;AAEnD,MAAI,QAAQ,MAAM;AAChB,WAAO;AAAA,EACT;AAEA,MAAI,OAAO;AACT,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB;AACA,SAAO;AACT;AAMO,IAAM,iBAAiB,CAAC,YAA6B;AAC1D,MAAI;AACF,qCAAc,OAAO;AACrB,WAAO;AAAA,EACT,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AACF;AAMO,IAAM,kBAAkB,CAAC,KAAa,QAAiB;AAC5D,MAAI,OAAO,QAAQ,aAAa;AAC9B,UAAM,OAAO,SAAS;AAAA,EACxB;AACA,QAAM,QAAQ,IAAI,MAAM,OAAO,GAAG,UAAU;AAC5C,SAAO,QAAQ,MAAM,CAAC,IAAI;AAC5B;AASO,IAAM,eAAe,CAC1B,KACA,KACA,iBACG;AACH,QAAM,OAAO,OAAO,SAAS;AAC7B,QAAM,CAAC,MAAM,MAAM,IAAI,KAAK,MAAM,GAAG;AACrC,QAAM,eAAe,IAAI,gBAAgB,MAAM;AAE/C,MAAI,aAAa,IAAI,GAAG,MAAM,QAAQ,CAAC,cAAc;AACnD;AAAA,EACF;AACA,eAAa,IAAI,KAAK,GAAG;AACzB,SAAO,SAAS,OAAO,GAAG,IAAI,IAAI,aAAa,SAAS,CAAC;AAC3D;AAQO,IAAM,uBAAuB,CAAC,QAAgB;AACnD,QAAM,OAAO,OAAO,SAAS;AAC7B,QAAM,CAAC,MAAM,MAAM,IAAI,KAAK,MAAM,GAAG;AACrC,QAAM,eAAe,IAAI,gBAAgB,MAAM;AAC/C,MAAI,aAAa,IAAI,GAAG,MAAM,MAAM;AAClC;AAAA,EACF;AACA,eAAa,OAAO,GAAG;AACvB,QAAM,cAAc,aAAa,SAAS;AAC1C,SAAO,SAAS,OAAO,GAAG,IAAI,GAAG,cAAc,IAAI,WAAW,KAAK,EAAE;AACvE;AAMO,IAAM,eACX,CAAC,cAAuB,CAAC,GAAY,MAAe;AAElD,MAAI,OAAO,MAAM,eAAe,OAAO,MAAM,aAAa;AACxD,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,MAAM,eAAe,OAAO,MAAM,aAAa;AACxD,WAAO,OAAO,MAAM,cAAc,IAAI;AAAA,EACxC;AAEA,MAAI,MAAM,GAAG;AACX,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,MAAM;AACd,WAAO;AAAA,EACT;AACA,MAAI,MAAM,MAAM;AACd,WAAO;AAAA,EACT;AAEA,MAAI,WAAW;AACb,WAAO,IAAI,IAAI,KAAK;AAAA,EACtB;AAEA,SAAO,IAAI,IAAI,IAAI;AACrB;AAMK,IAAM,sBAAsB,CACjC,YACA,iBACG;AACH,MAAI,aAAa,WAAW,WAAW,SAAS;AAC9C,iBAAa,QAAQ,MAAM,eAAe,GACxC,WAAW,QAAQ,cAAc,UAAU,MAAM,CACnD;AAAA,EACF;AACF;AAMO,IAAM,WAAW,CAAC,QAAgB,IAAI,QAAQ,QAAQ,GAAG;AAMzD,IAAM,WAAW,MAAM;AAC5B,QAAM,aAAc,QAA0C,UAAU;AACxE,QAAM,SAAU,QAAmB,aAAa;AAChD,QAAM,UACJ,OAAQ,QAAuC,QAAQ;AACzD,QAAM,WAAW,QAAQ,UAAU,QAAQ,KAAK,IAAI,MAAM;AAC1D,QAAM,cAAc,QAAQ,UAAU,MAAM,OAAO,KAAK;AAExD,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AACA,MACE,eAAe,QACf,OAAO,eAAe,eACtB,YAAY,SACZ,aAAa,OACb;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAOO,IAAM,UAAU,CACrB,OACA,OACA,SAEA,OAAO,UAAU,YAAY,OAAO,UAAU,YAAY,CAAC,KAAK,SAC5D,CAAC,IACD,MAAM;AAAA,EACJ,CAAC,cACC,CAAC,MAAM;AAAA,IAAK,CAAC,cACX,KAAK;AAAA,MAAM,CAAC,QACV,EAAE,OAAO,cAAc,EAAE,OAAO,aAC5B,QACA,UAAU,GAAG,MAAM,UAAU,GAAG;AAAA,IACtC;AAAA,EACF;AACJ;AAOC,IAAM,cAAc,CACzB,OACA,OACA,SAEA,OAAO,UAAU,YAAY,OAAO,UAAU,YAAY,CAAC,KAAK,SAC5D,CAAC,IACD,MAAM;AAAA,EACJ,CAAC,cACC,CAAC,MAAM;AAAA,IAAK,CAAC,cACX,KAAK;AAAA,MAAM,CAAC,QACV,EAAE,OAAO,cAAc,EAAE,OAAO,aAC5B,QACA,UAAU,GAAG,MAAM,UAAU,GAAG;AAAA,IACtC;AAAA,EACF;AACJ;AAOC,IAAM,oBAAoB,CAC/B,MACA,MACA,SAEA,OAAO,SAAS,YAAY,OAAO,SAAS,YAAY,CAAC,KAAK,SAC1D,CAAC,IACD,KAAK;AAAA,EAAO,CAAC,MACX,KAAK;AAAA,IAAK,CAAC,MACT,KAAK;AAAA,MAAM,CAAC,QACV,EAAE,OAAO,MAAM,EAAE,OAAO,KAAK,QAAQ,EAAE,GAAG,MAAM,EAAE,GAAG;AAAA,IACvD;AAAA,EACF;AACF;AAOC,IAAM,iBAAiB,CAAC,WAAmB;AAChD,MAAI;AACJ,MAAI;AACF,UAAM,IAAI,IAAI,MAAM;AAAA,EACtB,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AACA,SAAO,IAAI,aAAa,WAAW,IAAI,aAAa;AACtD;AAOO,IAAM,iBAAiB,CAAC,YAAgC;AAC7D,MAAI,cAAc;AAElB,QAAM,iBAAiB,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtD,YAAQ;AAAA,MAAK,CAAC,QACZ,cAAc,OAAO,MAAM,WAAW,CAAC,IAAI,QAAQ,GAAG;AAAA,IACxD;AACA,YAAQ;AAAA,MAAM,CAAC,UACb,cAAc,OAAO,MAAM,WAAW,CAAC,IAAI,OAAO,KAAK;AAAA,IACzD;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ,MAAM;AACZ,oBAAc;AAAA,IAChB;AAAA,EACF;AACF;AAQO,IAAM,gBAAgB,CAAC,EAAE,GAAG,MAAM,MAAM;AAE/C;AAQO,IAAM,YAAY,CACvB,WACG,YACW;AACd,MAAI,CAAC,QAAQ,QAAQ;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,CAAC,SAChB,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI;AACzD,QAAM,SAAS,QAAQ,MAAM;AAE7B,MAAI,SAAS,MAAM,KAAK,SAAS,MAAM,GAAG;AACxC,eAAW,OAAO,QAAQ;AACxB,UAAI,SAAS,OAAO,GAAG,CAAC,GAAG;AACzB,YAAI,CAAC,OAAO,GAAG,GAAG;AAChB,iBAAO,OAAO,QAAQ,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;AAAA,QACrC;AACA,kBAAU,OAAO,GAAG,GAAG,OAAO,GAAG,CAAC;AAAA,MACpC,OAAO;AACL,eAAO,OAAO,QAAQ,EAAE,CAAC,GAAG,GAAG,OAAO,GAAG,EAAE,CAAC;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;AACA,SAAO,UAAU,QAAQ,GAAG,OAAO;AACrC;","names":["import_utils"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/base.ts","../src/convert.ts","../src/unit.ts"],"sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nexport * from './base'\nexport * from './convert'\nexport * from './unit'\n","/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { encodeAddress } from 'dedot/utils'\n\n/**\n * Ensures a number has at least the specified number of decimal places, retaining commas in the output if they are present in the input.\n *\n * @function minDecimalPlaces\n * @param {string | number | BigInt} val - The input number, which can be a `string` with or without commas, a `number`, or a `BigInt`.\n * @param {number} minDecimals - The minimum number of decimal places to enforce.\n * @returns {string} The formatted number as a string, padded with zeros if needed to meet `minDecimals`, retaining commas if originally provided.\n * If `val` is invalid, returns \"0\".\n * @example\n * // Pads \"1,234.5\" to have at least 3 decimal places, with commas\n * minDecimalPlaces(\"1,234.5\", 3); // returns \"1,234.500\"\n *\n * // Returns \"1234.56\" unchanged\n * minDecimalPlaces(1234.56, 2); // returns \"1234.56\"\n *\n * // Pads BigInt 1234 with 2 decimals\n * minDecimalPlaces(BigInt(1234), 2); // returns \"1234.00\"\n */\nexport const minDecimalPlaces = (\n\tval: string | number | bigint,\n\tminDecimals: number,\n): string => {\n\ttry {\n\t\t// Determine if we should retain commas based on original input type\n\t\tconst retainCommas = typeof val === 'string' && val.includes(',')\n\n\t\t// Convert `val` to a plain string for processing\n\t\tconst strVal =\n\t\t\ttypeof val === 'string' ? val.replace(/,/g, '') : val.toString()\n\n\t\t// Separate integer and decimal parts\n\t\tconst [integerPart, fractionalPart = ''] = strVal.split('.')\n\n\t\t// Parse the integer part as a BigInt\n\t\tconst whole = BigInt(integerPart || '0')\n\n\t\t// Calculate missing decimal places\n\t\tconst missingDecimals = minDecimals - fractionalPart.length\n\n\t\t// Format the integer part back with commas only if the input had commas\n\t\tconst formattedWhole = retainCommas\n\t\t\t? Intl.NumberFormat('en-US').format(whole)\n\t\t\t: whole.toString()\n\n\t\t// If missing decimals are needed, pad with zeros; otherwise, return the original value\n\t\treturn missingDecimals > 0\n\t\t\t? `${formattedWhole}.${fractionalPart}${'0'.repeat(missingDecimals)}`\n\t\t\t: `${formattedWhole}.${fractionalPart}`\n\t} catch {\n\t\t// The provided value is not a valid number, return \"0\".\n\t\treturn '0'\n\t}\n}\n\n/**\n * @name camelize\n * @summary Converts a string of text to camelCase.\n */\nexport const camelize = (str: string) => {\n\tconst convertToString = (string: string) => {\n\t\tif (string) {\n\t\t\tif (typeof string === 'string') {\n\t\t\t\treturn string\n\t\t\t}\n\t\t\treturn String(string)\n\t\t}\n\t\treturn ''\n\t}\n\n\tconst toWords = (inp: string) =>\n\t\tconvertToString(inp).match(\n\t\t\t/[A-Z\\xC0-\\xD6\\xD8-\\xDE]?[a-z\\xDF-\\xF6\\xF8-\\xFF]+|[A-Z\\xC0-\\xD6\\xD8-\\xDE]+(?![a-z\\xDF-\\xF6\\xF8-\\xFF])|\\d+/g,\n\t\t)\n\n\tconst simpleCamelCase = (inp: string[]) => {\n\t\tlet result = ''\n\t\tfor (let i = 0; i < inp?.length; i++) {\n\t\t\tconst currString = inp[i]\n\t\t\tlet tmpStr = currString.toLowerCase()\n\t\t\tif (i !== 0) {\n\t\t\t\ttmpStr =\n\t\t\t\t\ttmpStr.slice(0, 1).toUpperCase() + tmpStr.slice(1, tmpStr.length)\n\t\t\t}\n\t\t\tresult += tmpStr\n\t\t}\n\t\treturn result\n\t}\n\n\tconst w = toWords(str)?.map((a) => a.toLowerCase())\n\treturn simpleCamelCase(w || [])\n}\n\n/**\n * @name ellipsisFn\n * @summary Receives an address and creates ellipsis on the given string, based on parameters.\n * @param str - The string to apply the ellipsis on\n * @param amount - The amount of characters that the ellipsis will be\n * @param position - where the ellipsis will apply; if center the amount of character is the\n * same for beginning and end; if \"start\" or \"end\" then its only once the amount; defaults to \"start\"\n */\nexport const ellipsisFn = (\n\tstr: string,\n\tamount = 6,\n\tposition: 'start' | 'end' | 'center' = 'center',\n) => {\n\tconst half = str.length / 2\n\n\t// having an amount less than 4 is a bit extreme so we default there\n\tif (amount <= 4) {\n\t\tif (position === 'center') {\n\t\t\treturn str.slice(0, 4) + '...' + str.slice(-4)\n\t\t}\n\t\tif (position === 'end') {\n\t\t\treturn str.slice(0, 4) + '...'\n\t\t}\n\t\treturn '...' + str.slice(-4)\n\t}\n\t// if the amount requested is in a \"logical\" amount - meaning that it can display the address\n\t// without repeating the same information twice - then go for it;\n\tif (position === 'center') {\n\t\treturn amount >= (str.length - 2) / 2\n\t\t\t? str.slice(0, half - 3) + '...' + str.slice(-(half - 3))\n\t\t\t: str.slice(0, amount) + '...' + str.slice(-amount)\n\t}\n\t// else, the user has been mistaskenly extreme, so just show the maximum possible amount\n\tif (amount >= str.length) {\n\t\tif (position === 'end') {\n\t\t\treturn str.slice(0, str.length - 3) + '...'\n\t\t}\n\t\treturn '...' + str.slice(-(str.length - 3))\n\t} else {\n\t\tif (position === 'end') {\n\t\t\treturn str.slice(0, amount) + '...'\n\t\t}\n\t\treturn '...' + str.slice(amount)\n\t}\n}\n\n/**\n * @name pageFromUri\n * @summary Use url variables to load the default components upon the first page visit.\n */\nexport const pageFromUri = (pathname: string, fallback: string) => {\n\tconst lastUriItem = pathname.substring(pathname.lastIndexOf('/') + 1)\n\tconst page = lastUriItem.trim() === '' ? fallback : lastUriItem\n\treturn page.trim()\n}\n\n/**\n * @name rmCommas\n * @summary Removes the commas from a string.\n */\nexport const rmCommas = (val: string): string => val.replace(/,/g, '')\n\n/**\n * @name rmDecimals\n * @summary Removes the decimal point and decimals from a string.\n */\nexport const rmDecimals = (str: string) => str.split('.')[0]\n\n/**\n * @name shuffle\n * @summary Shuffle a set of objects.\n */\nexport const shuffle = <T>(array: T[]) => {\n\tlet currentIndex = array.length\n\tlet randomIndex\n\twhile (currentIndex !== 0) {\n\t\trandomIndex = Math.floor(Math.random() * currentIndex)\n\t\tcurrentIndex--\n\t\t;[array[currentIndex], array[randomIndex]] = [\n\t\t\tarray[randomIndex],\n\t\t\tarray[currentIndex],\n\t\t]\n\t}\n\treturn array\n}\n\n/**\n * @name withTimeout\n * @summary Timeout a promise after a specified number of milliseconds.\n */\nexport const withTimeout = (\n\tms: number,\n\tpromise: Promise<unknown>,\n\toptions?: {\n\t\tonTimeout?: () => void\n\t},\n) => {\n\tconst timeout = new Promise((resolve) =>\n\t\tsetTimeout(async () => {\n\t\t\tif (typeof options?.onTimeout === 'function') {\n\t\t\t\toptions.onTimeout()\n\t\t\t}\n\t\t\tresolve(undefined)\n\t\t}, ms),\n\t)\n\treturn Promise.race([promise, timeout])\n}\n\n/**\n * @name withTimeoutThrow\n * @summary Timeout a promise after a specified number of milliseconds by throwing an error\n */\nexport const withTimeoutThrow = <T>(\n\tms: number,\n\tpromise: Promise<T>,\n\toptions?: {\n\t\tonTimeout?: () => void\n\t},\n) => {\n\tconst timeout = new Promise((reject) =>\n\t\tsetTimeout(async () => {\n\t\t\tif (typeof options?.onTimeout === 'function') {\n\t\t\t\toptions.onTimeout()\n\t\t\t}\n\t\t\treject('Function timeout')\n\t\t}, ms),\n\t)\n\treturn Promise.race([promise, timeout])\n}\n\n/**\n * @name appendOrEmpty\n * @summary Returns ` value` if a condition is truthy, or an empty string otherwise.\n */\nexport const appendOrEmpty = (\n\tcondition: boolean | string | undefined,\n\tvalue: string,\n) => (condition ? ` ${value}` : '')\n\n/**\n * @name appendOr\n * @summary Returns ` value` if condition is truthy, or ` fallback` otherwise.\n */\nexport const appendOr = (\n\tcondition: boolean | string | undefined,\n\tvalue: string,\n\tfallback: string,\n) => (condition ? ` ${value}` : ` ${fallback}`)\n\n/**\n * @name formatAccountSs58\n * @summary Formats an address with the supplied ss58 prefix, or returns null if invalid.\n */\nexport const formatAccountSs58 = (\n\taddress: string,\n\tss58: number,\n): string | null => {\n\ttry {\n\t\treturn encodeAddress(address, ss58)\n\t} catch {\n\t\treturn null\n\t}\n}\n\n/**\n * @name tryFormatSs58\n * @summary Formats an address with the supplied ss58 prefix, or returns the original address if\n * invalid.\n */\nexport const tryFormatSs58 = (address: string, ss58: number): string => {\n\ttry {\n\t\treturn encodeAddress(address, ss58)\n\t} catch {\n\t\treturn address\n\t}\n}\n\n/**\n * @name removeHexPrefix\n * @summary Takes a string str as input and returns a new string with the \"0x\" prefix removed if it\n * exists at the beginning of the input string.\n */\nexport const removeHexPrefix = (str: string): string => str.replace(/^0x/, '')\n\n// Check if 2 sets contain the same elements.\n// biome-ignore lint/suspicious/noExplicitAny: <>\nexport const eqSet = (xs: Set<any>, ys: Set<any>) =>\n\txs.size === ys.size && [...xs].every((x) => ys.has(x))\n\n// Check if one set contains all the elements of another set.\n// biome-ignore lint/suspicious/noExplicitAny: <>\nexport const isSuperset = (set: Set<any>, subset: Set<any>) => {\n\tfor (const elem of subset) {\n\t\tif (!set.has(elem)) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n/**\n * Finds the maximum value among a list of BigInt values.\n *\n * @function maxBigInt\n * @param {...bigint} values - A list of BigInt values to compare.\n * @returns {bigint} The largest BigInt value in the provided list.\n * @example\n * // Returns the maximum BigInt value\n * maxBigInt(10n, 50n, 30n, 100n, 20n); // 100n\n */\nexport const maxBigInt = (...values: bigint[]): bigint =>\n\tvalues.reduce((max, current) => (current > max ? current : max))\n\n/**\n * Finds the minimum value among a list of BigInt values.\n *\n * @function minBigInt\n * @param {...bigint} values - A list of BigInt values to compare.\n * @returns {bigint} The smallest BigInt value in the provided list.\n * @example\n * // Returns the minimum BigInt value\n * minBigInt(10n, 50n, 30n, 100n, 20n); // 10n\n */\nexport const minBigInt = (...values: bigint[]): bigint =>\n\tvalues.reduce((min, current) => (current < min ? current : min))\n","// /* @license Copyright 2024 w3ux authors & contributors\n// SPDX-License-Identifier: GPL-3.0-only */\n\n/**\n * Concatenates multiple Uint8Array instances into a single Uint8Array.\n *\n * @param {Uint8Array[]} u8as - An array of Uint8Array instances to concatenate.\n * @returns {Uint8Array} A new Uint8Array containing all the input arrays concatenated.\n */\nexport const u8aConcat = (...u8as: Uint8Array[]): Uint8Array => {\n\t// Calculate the total length of the resulting Uint8Array\n\tconst totalLength = u8as.reduce((sum, u8a) => sum + u8a.length, 0)\n\n\t// Create a new Uint8Array with the total length\n\tconst result = new Uint8Array(totalLength)\n\n\tlet offset = 0 // Initialize the offset for placing elements\n\tfor (const u8a of u8as) {\n\t\tresult.set(u8a, offset) // Set the current Uint8Array at the current offset\n\t\toffset += u8a.length // Update the offset for the next Uint8Array\n\t}\n\n\treturn result\n}\n","/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { decodeAddress } from 'dedot/utils'\nimport type { RefObject } from 'react'\nimport { rmCommas, rmDecimals } from './base'\nimport type { AnyObject } from './types'\n\n/**\n * Converts an on-chain balance value from planck to a decimal value in token units.\n *\n * @function planckToUnit\n * @param {number | BigInt | string} val - The balance value in planck. Accepts a `number`, `BigInt`, or `string`.\n * @param {number} units - The number of decimal places in the token unit (10^units planck per 1 token).\n * @returns {string} The equivalent token unit value as a decimal string.\n * @example\n * // Convert 1500000000000 planck to tokens with 12 decimal places\n * planckToUnit(\"1500000000000\", 12); // returns \"1.5\"\n */\nexport const planckToUnit = (\n\tval: number | bigint | string,\n\tunits: number,\n): string => {\n\ttry {\n\t\t// Ensure `units` is a positive integer.\n\t\tunits = Math.max(Math.round(units), 0)\n\n\t\t// Convert `val` to BigInt based on its type\n\t\tconst bigIntVal =\n\t\t\ttypeof val === 'bigint'\n\t\t\t\t? val\n\t\t\t\t: BigInt(\n\t\t\t\t\t\ttypeof val === 'number'\n\t\t\t\t\t\t\t? Math.floor(val).toString()\n\t\t\t\t\t\t\t: rmDecimals(rmCommas(val)),\n\t\t\t\t\t)\n\n\t\tconst divisor = units === 0 ? 1n : BigInt(10) ** BigInt(units)\n\n\t\t// Integer division and remainder for the fractional part\n\t\tconst integerPart = bigIntVal / divisor\n\t\tconst fractionalPart = bigIntVal % divisor\n\n\t\t// Format fractional part with leading zeros to maintain `units` decimal places\n\t\tconst fractionalStr =\n\t\t\tunits > 0 ? `.${fractionalPart.toString().padStart(units, '0')}` : ``\n\n\t\t// Combine integer and fractional parts as a decimal string\n\t\treturn `${integerPart}${fractionalStr}`\n\t} catch {\n\t\treturn '0'\n\t}\n}\n\n/**\n * Converts a token unit value to an integer value in planck.\n *\n * @function unitToPlanck\n * @param {string | number | BigInt} val - The token unit value to convert. Accepts a string, number, or BigInt.\n * @param {number} units - The number of decimal places for conversion (10^units planck per 1 token).\n * @returns {BigInt} The equivalent value in planck as a BigInt.\n * @example\n * // Convert \"1.5\" tokens to planck with 12 decimal places\n * unitToPlanck(\"1.5\", 12); // returns BigInt(\"1500000000000\")\n */\nexport const unitToPlanck = (\n\tval: string | number | bigint,\n\tunits: number,\n): bigint => {\n\ttry {\n\t\t// Ensure `units` is a positive integer.\n\t\tunits = Math.max(Math.round(units), 0)\n\n\t\t// Convert `val` to a string; if empty or invalid, default to \"0\"\n\t\tconst strVal =\n\t\t\t(typeof val === 'string' ? rmCommas(val) : val.toString()) || '0'\n\n\t\t// Split into integer and fractional parts\n\t\tconst [integerPart, fractionalPart = ''] = strVal.split('.')\n\n\t\t// Process the integer part by converting to BigInt and scaling it to the given units\n\t\tlet bigIntValue = BigInt(integerPart) * BigInt(10) ** BigInt(units)\n\n\t\t// Process the fractional part if it exists\n\t\tif (fractionalPart) {\n\t\t\tlet fractionalValue: bigint\n\n\t\t\tif (fractionalPart.length > units) {\n\t\t\t\t// If fractional part exceeds units, truncate it\n\t\t\t\tfractionalValue = BigInt(fractionalPart.slice(0, units))\n\t\t\t} else {\n\t\t\t\t// Otherwise, pad the fractional part to match units\n\t\t\t\tfractionalValue = BigInt(fractionalPart.padEnd(units, '0'))\n\t\t\t}\n\n\t\t\tbigIntValue += fractionalValue\n\t\t}\n\n\t\treturn bigIntValue\n\t} catch {\n\t\treturn BigInt(0)\n\t}\n}\n\n/**\n * @name remToUnit\n * @summary Converts a rem string to a number.\n */\nexport const remToUnit = (rem: string) =>\n\tNumber(rem.slice(0, rem.length - 3)) *\n\tparseFloat(getComputedStyle(document.documentElement).fontSize)\n\n/**\n * @name capitalizeFirstLetter\n * @summary Capitalize the first letter of a string.\n */\nexport const capitalizeFirstLetter = (string: string) =>\n\tstring.charAt(0).toUpperCase() + string.slice(1)\n\n/**\n * @name snakeToCamel\n * @summary converts a string from snake / kebab-case to camel-case.\n */\nexport const snakeToCamel = (str: string) =>\n\tstr\n\t\t.toLowerCase()\n\t\t.replace(/([-_][a-z])/g, (group) =>\n\t\t\tgroup.toUpperCase().replace('-', '').replace('_', ''),\n\t\t)\n\n/**\n * @name setStateWithRef\n * @summary Synchronize React state and its reference with the provided value.\n */\nexport const setStateWithRef = <T>(\n\tvalue: T,\n\tsetState: (_state: T) => void,\n\tref: RefObject<T>,\n): void => {\n\tsetState(value)\n\tref.current = value\n}\n\n/**\n * @name localStorageOrDefault\n * @summary Retrieve the local stroage value with the key, return defult value if it is not\n * found.\n */\nexport const localStorageOrDefault = <T>(\n\tkey: string,\n\t_default: T,\n\tparse = false,\n): T | string => {\n\tconst val: string | null = localStorage.getItem(key)\n\n\tif (val === null) {\n\t\treturn _default\n\t}\n\n\tif (parse) {\n\t\treturn JSON.parse(val) as T\n\t}\n\treturn val\n}\n\n/**\n * @name isValidAddress\n * @summary Return whether an address is valid Substrate address.\n */\nexport const isValidAddress = (address: string): boolean => {\n\ttry {\n\t\tdecodeAddress(address)\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * @name extractUrlValue\n * @summary Extracts a URL value from a URL string.\n */\nexport const extractUrlValue = (key: string, url?: string) => {\n\tif (typeof url === 'undefined') {\n\t\turl = window.location.href\n\t}\n\tconst match = url.match(`[?&]${key}=([^&]+)`)\n\treturn match ? match[1] : null\n}\n\n/**\n * @name varToUrlHash\n * @summary Puts a variable into the URL hash as a param.\n * @description\n * Since url variables are added to the hash and are not treated as URL params, the params are split\n * and parsed into a `URLSearchParams`.\n */\nexport const varToUrlHash = (\n\tkey: string,\n\tval: string,\n\taddIfMissing: boolean,\n) => {\n\tconst hash = window.location.hash\n\tconst [page, params] = hash.split('?')\n\tconst searchParams = new URLSearchParams(params)\n\n\tif (searchParams.get(key) === null && !addIfMissing) {\n\t\treturn\n\t}\n\tsearchParams.set(key, val)\n\twindow.location.hash = `${page}?${searchParams.toString()}`\n}\n\n/**\n * @name removeVarFromUrlHash\n * @summary\n * Removes a variable `key` from the URL hash if it exists. Removes dangling `?` if no URL variables\n * exist.\n */\nexport const removeVarFromUrlHash = (key: string) => {\n\tconst hash = window.location.hash\n\tconst [page, params] = hash.split('?')\n\tconst searchParams = new URLSearchParams(params)\n\tif (searchParams.get(key) === null) {\n\t\treturn\n\t}\n\tsearchParams.delete(key)\n\tconst paramsAsStr = searchParams.toString()\n\twindow.location.hash = `${page}${paramsAsStr ? `?${paramsAsStr}` : ``}`\n}\n\n/**\n * @name sortWithNull\n * @summary Sorts an array with nulls last.\n */\nexport const sortWithNull =\n\t(ascending: boolean) => (a: unknown, b: unknown) => {\n\t\t// if both items are undefined, treat them as equal\n\t\tif (typeof a === 'undefined' && typeof b === 'undefined') {\n\t\t\treturn 0\n\t\t}\n\t\t// if either item is undefined, sort it last\n\t\tif (typeof a === 'undefined' || typeof b === 'undefined') {\n\t\t\treturn typeof a === 'undefined' ? 1 : -1\n\t\t}\n\t\t// equal items sort equally\n\t\tif (a === b) {\n\t\t\treturn 0\n\t\t}\n\t\t// nulls sort after anything else\n\t\tif (a === null) {\n\t\t\treturn 1\n\t\t}\n\t\tif (b === null) {\n\t\t\treturn -1\n\t\t}\n\t\t// otherwise, if we're ascending, lowest sorts first\n\t\tif (ascending) {\n\t\t\treturn a < b ? -1 : 1\n\t\t}\n\t\t// if descending, highest sorts first\n\t\treturn a < b ? 1 : -1\n\t}\n\n/**\n * @name applyWidthAsPadding\n * @summary Applies width of subject to paddingRight of container.\n */\nexport const applyWidthAsPadding = (\n\tsubjectRef: RefObject<HTMLDivElement | null>,\n\tcontainerRef: RefObject<HTMLDivElement | null>,\n) => {\n\tif (containerRef.current && subjectRef.current) {\n\t\tcontainerRef.current.style.paddingRight = `${\n\t\t\tsubjectRef.current.offsetWidth + remToUnit('1rem')\n\t\t}px`\n\t}\n}\n\n/**\n * @name unescape\n * @summary Replaces \\” with “\n */\nexport const unescape = (val: string) => val.replace(/\\\\\"/g, '\"')\n\n/**\n * @name inChrome\n * @summary Whether the application is rendering in Chrome.\n */\nexport const inChrome = () => {\n\tconst isChromium = (window as Window & { chrome?: boolean })?.chrome || null\n\tconst winNav = (window as Window)?.navigator || null\n\tconst isOpera =\n\t\ttypeof (window as Window & { opr?: boolean })?.opr !== 'undefined'\n\tconst isIEedge = winNav?.userAgent.indexOf('Edg') > -1 || false\n\tconst isIOSChrome = winNav?.userAgent.match('CriOS') || false\n\n\tif (isIOSChrome) {\n\t\treturn true\n\t}\n\tif (\n\t\tisChromium !== null &&\n\t\ttypeof isChromium !== 'undefined' &&\n\t\tisOpera === false &&\n\t\tisIEedge === false\n\t) {\n\t\treturn true\n\t}\n\treturn false\n}\n\n/**\n * @name addedTo\n * @summary Given 2 objects and some keys, return items in the fresh object that do not exist in the\n * stale object by matching the given common key values of both objects.\n */\nexport const addedTo = (\n\tfresh: AnyObject[],\n\tstale: AnyObject[],\n\tkeys: string[],\n): AnyObject[] =>\n\ttypeof fresh !== 'object' || typeof stale !== 'object' || !keys.length\n\t\t? []\n\t\t: fresh.filter(\n\t\t\t\t(freshItem) =>\n\t\t\t\t\t!stale.find((staleItem) =>\n\t\t\t\t\t\tkeys.every((key) =>\n\t\t\t\t\t\t\t!(key in staleItem) || !(key in freshItem)\n\t\t\t\t\t\t\t\t? false\n\t\t\t\t\t\t\t\t: staleItem[key] === freshItem[key],\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t)\n\n/**\n * @name removedFrom\n * @summary Given 2 objects and some keys, return items in the stale object that do not exist in the\n * fresh object by matching the given common key values of both objects.\n */\nexport const removedFrom = (\n\tfresh: AnyObject[],\n\tstale: AnyObject[],\n\tkeys: string[],\n): AnyObject[] =>\n\ttypeof fresh !== 'object' || typeof stale !== 'object' || !keys.length\n\t\t? []\n\t\t: stale.filter(\n\t\t\t\t(staleItem) =>\n\t\t\t\t\t!fresh.find((freshItem) =>\n\t\t\t\t\t\tkeys.every((key) =>\n\t\t\t\t\t\t\t!(key in staleItem) || !(key in freshItem)\n\t\t\t\t\t\t\t\t? false\n\t\t\t\t\t\t\t\t: freshItem[key] === staleItem[key],\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t)\n\n/**\n * @name matchedProperties\n * @summary Given 2 objects and some keys, return items in object 1 that also exist in object 2 by\n * matching the given common key values of both objects.\n */\nexport const matchedProperties = (\n\tobjX: AnyObject[],\n\tobjY: AnyObject[],\n\tkeys: string[],\n): AnyObject[] =>\n\ttypeof objX !== 'object' || typeof objY !== 'object' || !keys.length\n\t\t? []\n\t\t: objY.filter((x) =>\n\t\t\t\tobjX.find((y) =>\n\t\t\t\t\tkeys.every((key) =>\n\t\t\t\t\t\t!(key in x) || !(key in y) ? false : y[key] === x[key],\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\n/**\n * @name isValidHttpUrl\n * @summary Give a string, return whether it is a valid http URL.\n * @param string - The string to check.\n */\nexport const isValidHttpUrl = (string: string) => {\n\tlet url: URL\n\ttry {\n\t\turl = new URL(string)\n\t} catch (_) {\n\t\treturn false\n\t}\n\treturn url.protocol === 'http:' || url.protocol === 'https:'\n}\n\n/**\n * @name makeCancelable\n * @summary Makes a promise cancellable.\n * @param promise - The promise to make cancellable.\n */\nexport const makeCancelable = (promise: Promise<AnyObject>) => {\n\tlet hasCanceled = false\n\n\tconst wrappedPromise = new Promise((resolve, reject) => {\n\t\tpromise.then((val) =>\n\t\t\thasCanceled ? reject(Error('Cancelled')) : resolve(val),\n\t\t)\n\t\tpromise.catch((error) =>\n\t\t\thasCanceled ? reject(Error('Cancelled')) : reject(error),\n\t\t)\n\t})\n\n\treturn {\n\t\tpromise: wrappedPromise,\n\t\tcancel: () => {\n\t\t\thasCanceled = true\n\t\t},\n\t}\n}\n\n/**\n * @name unimplemented\n * @summary A placeholder function to signal a deliberate unimplementation.\n * Consumes an arbitrary number of props.\n */\nexport const unimplemented = (_props?: unknown) => {\n\t/* unimplemented */\n}\n\n/**\n * Deep merge two objects.\n * @param target\n * @param ...sources\n */\n\nexport const mergeDeep = (\n\ttarget: AnyObject,\n\t...sources: AnyObject[]\n): AnyObject => {\n\tif (!sources.length) {\n\t\treturn target\n\t}\n\n\tconst isObject = (item: AnyObject) =>\n\t\titem && typeof item === 'object' && !Array.isArray(item)\n\tconst source = sources.shift()\n\n\tif (isObject(target) && isObject(source)) {\n\t\tfor (const key in source) {\n\t\t\tif (isObject(source[key])) {\n\t\t\t\tif (!target[key]) {\n\t\t\t\t\tObject.assign(target, { [key]: {} })\n\t\t\t\t}\n\t\t\t\tmergeDeep(target[key], source[key])\n\t\t\t} else {\n\t\t\t\tObject.assign(target, { [key]: source[key] })\n\t\t\t}\n\t\t}\n\t}\n\treturn mergeDeep(target, ...sources)\n}\n"],"mappings":"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","names":["import_utils"]}
package/index.d.cts CHANGED
@@ -262,9 +262,7 @@ declare const makeCancelable: (promise: Promise<AnyObject>) => {
262
262
  * @summary A placeholder function to signal a deliberate unimplementation.
263
263
  * Consumes an arbitrary number of props.
264
264
  */
265
- declare const unimplemented: ({ ...props }: {
266
- [x: string]: any;
267
- }) => void;
265
+ declare const unimplemented: (_props?: unknown) => void;
268
266
  /**
269
267
  * Deep merge two objects.
270
268
  * @param target
package/index.d.ts CHANGED
@@ -262,9 +262,7 @@ declare const makeCancelable: (promise: Promise<AnyObject>) => {
262
262
  * @summary A placeholder function to signal a deliberate unimplementation.
263
263
  * Consumes an arbitrary number of props.
264
264
  */
265
- declare const unimplemented: ({ ...props }: {
266
- [x: string]: any;
267
- }) => void;
265
+ declare const unimplemented: (_props?: unknown) => void;
268
266
  /**
269
267
  * Deep merge two objects.
270
268
  * @param target
package/index.js CHANGED
@@ -9,7 +9,7 @@ var minDecimalPlaces = (val, minDecimals) => {
9
9
  const missingDecimals = minDecimals - fractionalPart.length;
10
10
  const formattedWhole = retainCommas ? Intl.NumberFormat("en-US").format(whole) : whole.toString();
11
11
  return missingDecimals > 0 ? `${formattedWhole}.${fractionalPart}${"0".repeat(missingDecimals)}` : `${formattedWhole}.${fractionalPart}`;
12
- } catch (e) {
12
+ } catch {
13
13
  return "0";
14
14
  }
15
15
  };
@@ -31,7 +31,7 @@ var camelize = (str) => {
31
31
  for (let i = 0; i < inp?.length; i++) {
32
32
  const currString = inp[i];
33
33
  let tmpStr = currString.toLowerCase();
34
- if (i != 0) {
34
+ if (i !== 0) {
35
35
  tmpStr = tmpStr.slice(0, 1).toUpperCase() + tmpStr.slice(1, tmpStr.length);
36
36
  }
37
37
  result += tmpStr;
@@ -114,14 +114,14 @@ var appendOr = (condition, value, fallback) => condition ? ` ${value}` : ` ${fal
114
114
  var formatAccountSs58 = (address, ss58) => {
115
115
  try {
116
116
  return encodeAddress(address, ss58);
117
- } catch (e) {
117
+ } catch {
118
118
  return null;
119
119
  }
120
120
  };
121
121
  var tryFormatSs58 = (address, ss58) => {
122
122
  try {
123
123
  return encodeAddress(address, ss58);
124
- } catch (e) {
124
+ } catch {
125
125
  return address;
126
126
  }
127
127
  };
@@ -163,7 +163,7 @@ var planckToUnit = (val, units) => {
163
163
  const fractionalPart = bigIntVal % divisor;
164
164
  const fractionalStr = units > 0 ? `.${fractionalPart.toString().padStart(units, "0")}` : ``;
165
165
  return `${integerPart}${fractionalStr}`;
166
- } catch (e) {
166
+ } catch {
167
167
  return "0";
168
168
  }
169
169
  };
@@ -183,7 +183,7 @@ var unitToPlanck = (val, units) => {
183
183
  bigIntValue += fractionalValue;
184
184
  }
185
185
  return bigIntValue;
186
- } catch (e) {
186
+ } catch {
187
187
  return BigInt(0);
188
188
  }
189
189
  };
@@ -211,7 +211,7 @@ var isValidAddress = (address) => {
211
211
  try {
212
212
  decodeAddress(address);
213
213
  return true;
214
- } catch (e) {
214
+ } catch {
215
215
  return false;
216
216
  }
217
217
  };
@@ -331,7 +331,7 @@ var makeCancelable = (promise) => {
331
331
  }
332
332
  };
333
333
  };
334
- var unimplemented = ({ ...props }) => {
334
+ var unimplemented = (_props) => {
335
335
  };
336
336
  var mergeDeep = (target, ...sources) => {
337
337
  if (!sources.length) {
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/base.ts","../src/convert.ts","../src/unit.ts"],"sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { encodeAddress } from 'dedot/utils'\n\n/**\n * Ensures a number has at least the specified number of decimal places, retaining commas in the output if they are present in the input.\n *\n * @function minDecimalPlaces\n * @param {string | number | BigInt} val - The input number, which can be a `string` with or without commas, a `number`, or a `BigInt`.\n * @param {number} minDecimals - The minimum number of decimal places to enforce.\n * @returns {string} The formatted number as a string, padded with zeros if needed to meet `minDecimals`, retaining commas if originally provided.\n * If `val` is invalid, returns \"0\".\n * @example\n * // Pads \"1,234.5\" to have at least 3 decimal places, with commas\n * minDecimalPlaces(\"1,234.5\", 3); // returns \"1,234.500\"\n *\n * // Returns \"1234.56\" unchanged\n * minDecimalPlaces(1234.56, 2); // returns \"1234.56\"\n *\n * // Pads BigInt 1234 with 2 decimals\n * minDecimalPlaces(BigInt(1234), 2); // returns \"1234.00\"\n */\nexport const minDecimalPlaces = (\n val: string | number | bigint,\n minDecimals: number\n): string => {\n try {\n // Determine if we should retain commas based on original input type\n const retainCommas = typeof val === 'string' && val.includes(',')\n\n // Convert `val` to a plain string for processing\n const strVal =\n typeof val === 'string' ? val.replace(/,/g, '') : val.toString()\n\n // Separate integer and decimal parts\n const [integerPart, fractionalPart = ''] = strVal.split('.')\n\n // Parse the integer part as a BigInt\n const whole = BigInt(integerPart || '0')\n\n // Calculate missing decimal places\n const missingDecimals = minDecimals - fractionalPart.length\n\n // Format the integer part back with commas only if the input had commas\n const formattedWhole = retainCommas\n ? Intl.NumberFormat('en-US').format(whole)\n : whole.toString()\n\n // If missing decimals are needed, pad with zeros; otherwise, return the original value\n return missingDecimals > 0\n ? `${formattedWhole}.${fractionalPart}${'0'.repeat(missingDecimals)}`\n : `${formattedWhole}.${fractionalPart}`\n } catch (e) {\n // The provided value is not a valid number, return \"0\".\n return '0'\n }\n}\n\n/**\n * @name camelize\n * @summary Converts a string of text to camelCase.\n */\nexport const camelize = (str: string) => {\n const convertToString = (string: string) => {\n if (string) {\n if (typeof string === 'string') {\n return string\n }\n return String(string)\n }\n return ''\n }\n\n const toWords = (inp: string) =>\n convertToString(inp).match(\n /[A-Z\\xC0-\\xD6\\xD8-\\xDE]?[a-z\\xDF-\\xF6\\xF8-\\xFF]+|[A-Z\\xC0-\\xD6\\xD8-\\xDE]+(?![a-z\\xDF-\\xF6\\xF8-\\xFF])|\\d+/g\n )\n\n const simpleCamelCase = (inp: string[]) => {\n let result = ''\n for (let i = 0; i < inp?.length; i++) {\n const currString = inp[i]\n let tmpStr = currString.toLowerCase()\n if (i != 0) {\n tmpStr =\n tmpStr.slice(0, 1).toUpperCase() + tmpStr.slice(1, tmpStr.length)\n }\n result += tmpStr\n }\n return result\n }\n\n const w = toWords(str)?.map((a) => a.toLowerCase())\n return simpleCamelCase(w || [])\n}\n\n/**\n * @name ellipsisFn\n * @summary Receives an address and creates ellipsis on the given string, based on parameters.\n * @param str - The string to apply the ellipsis on\n * @param amount - The amount of characters that the ellipsis will be\n * @param position - where the ellipsis will apply; if center the amount of character is the\n * same for beginning and end; if \"start\" or \"end\" then its only once the amount; defaults to \"start\"\n */\nexport const ellipsisFn = (\n str: string,\n amount = 6,\n position: 'start' | 'end' | 'center' = 'center'\n) => {\n const half = str.length / 2\n\n // having an amount less than 4 is a bit extreme so we default there\n if (amount <= 4) {\n if (position === 'center') {\n return str.slice(0, 4) + '...' + str.slice(-4)\n }\n if (position === 'end') {\n return str.slice(0, 4) + '...'\n }\n return '...' + str.slice(-4)\n }\n // if the amount requested is in a \"logical\" amount - meaning that it can display the address\n // without repeating the same information twice - then go for it;\n if (position === 'center') {\n return amount >= (str.length - 2) / 2\n ? str.slice(0, half - 3) + '...' + str.slice(-(half - 3))\n : str.slice(0, amount) + '...' + str.slice(-amount)\n }\n // else, the user has been mistaskenly extreme, so just show the maximum possible amount\n if (amount >= str.length) {\n if (position === 'end') {\n return str.slice(0, str.length - 3) + '...'\n }\n return '...' + str.slice(-(str.length - 3))\n } else {\n if (position === 'end') {\n return str.slice(0, amount) + '...'\n }\n return '...' + str.slice(amount)\n }\n}\n\n/**\n * @name pageFromUri\n * @summary Use url variables to load the default components upon the first page visit.\n */\nexport const pageFromUri = (pathname: string, fallback: string) => {\n const lastUriItem = pathname.substring(pathname.lastIndexOf('/') + 1)\n const page = lastUriItem.trim() === '' ? fallback : lastUriItem\n return page.trim()\n}\n\n/**\n * @name rmCommas\n * @summary Removes the commas from a string.\n */\nexport const rmCommas = (val: string): string => val.replace(/,/g, '')\n\n/**\n * @name rmDecimals\n * @summary Removes the decimal point and decimals from a string.\n */\nexport const rmDecimals = (str: string) => str.split('.')[0]\n\n/**\n * @name shuffle\n * @summary Shuffle a set of objects.\n */\nexport const shuffle = <T>(array: T[]) => {\n let currentIndex = array.length\n let randomIndex\n while (currentIndex !== 0) {\n randomIndex = Math.floor(Math.random() * currentIndex)\n currentIndex--\n ;[array[currentIndex], array[randomIndex]] = [\n array[randomIndex],\n array[currentIndex],\n ]\n }\n return array\n}\n\n/**\n * @name withTimeout\n * @summary Timeout a promise after a specified number of milliseconds.\n */\nexport const withTimeout = (\n ms: number,\n promise: Promise<unknown>,\n options?: {\n onTimeout?: () => void\n }\n) => {\n const timeout = new Promise((resolve) =>\n setTimeout(async () => {\n if (typeof options?.onTimeout === 'function') {\n options.onTimeout()\n }\n resolve(undefined)\n }, ms)\n )\n return Promise.race([promise, timeout])\n}\n\n/**\n * @name withTimeoutThrow\n * @summary Timeout a promise after a specified number of milliseconds by throwing an error\n */\nexport const withTimeoutThrow = <T>(\n ms: number,\n promise: Promise<T>,\n options?: {\n onTimeout?: () => void\n }\n) => {\n const timeout = new Promise((reject) =>\n setTimeout(async () => {\n if (typeof options?.onTimeout === 'function') {\n options.onTimeout()\n }\n reject('Function timeout')\n }, ms)\n )\n return Promise.race([promise, timeout])\n}\n\n/**\n * @name appendOrEmpty\n * @summary Returns ` value` if a condition is truthy, or an empty string otherwise.\n */\nexport const appendOrEmpty = (\n condition: boolean | string | undefined,\n value: string\n) => (condition ? ` ${value}` : '')\n\n/**\n * @name appendOr\n * @summary Returns ` value` if condition is truthy, or ` fallback` otherwise.\n */\nexport const appendOr = (\n condition: boolean | string | undefined,\n value: string,\n fallback: string\n) => (condition ? ` ${value}` : ` ${fallback}`)\n\n/**\n * @name formatAccountSs58\n * @summary Formats an address with the supplied ss58 prefix, or returns null if invalid.\n */\nexport const formatAccountSs58 = (\n address: string,\n ss58: number\n): string | null => {\n try {\n return encodeAddress(address, ss58)\n } catch (e) {\n return null\n }\n}\n\n/**\n * @name tryFormatSs58\n * @summary Formats an address with the supplied ss58 prefix, or returns the original address if\n * invalid.\n */\nexport const tryFormatSs58 = (address: string, ss58: number): string => {\n try {\n return encodeAddress(address, ss58)\n } catch (e) {\n return address\n }\n}\n\n/**\n * @name removeHexPrefix\n * @summary Takes a string str as input and returns a new string with the \"0x\" prefix removed if it\n * exists at the beginning of the input string.\n */\nexport const removeHexPrefix = (str: string): string => str.replace(/^0x/, '')\n\n// Check if 2 sets contain the same elements.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const eqSet = (xs: Set<any>, ys: Set<any>) =>\n xs.size === ys.size && [...xs].every((x) => ys.has(x))\n\n// Check if one set contains all the elements of another set.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isSuperset = (set: Set<any>, subset: Set<any>) => {\n for (const elem of subset) {\n if (!set.has(elem)) {\n return false\n }\n }\n return true\n}\n\n/**\n * Finds the maximum value among a list of BigInt values.\n *\n * @function maxBigInt\n * @param {...bigint} values - A list of BigInt values to compare.\n * @returns {bigint} The largest BigInt value in the provided list.\n * @example\n * // Returns the maximum BigInt value\n * maxBigInt(10n, 50n, 30n, 100n, 20n); // 100n\n */\nexport const maxBigInt = (...values: bigint[]): bigint =>\n values.reduce((max, current) => (current > max ? current : max))\n\n/**\n * Finds the minimum value among a list of BigInt values.\n *\n * @function minBigInt\n * @param {...bigint} values - A list of BigInt values to compare.\n * @returns {bigint} The smallest BigInt value in the provided list.\n * @example\n * // Returns the minimum BigInt value\n * minBigInt(10n, 50n, 30n, 100n, 20n); // 10n\n */\nexport const minBigInt = (...values: bigint[]): bigint =>\n values.reduce((min, current) => (current < min ? current : min))\n","// /* @license Copyright 2024 w3ux authors & contributors\n// SPDX-License-Identifier: GPL-3.0-only */\n\n/**\n * Concatenates multiple Uint8Array instances into a single Uint8Array.\n *\n * @param {Uint8Array[]} u8as - An array of Uint8Array instances to concatenate.\n * @returns {Uint8Array} A new Uint8Array containing all the input arrays concatenated.\n */\nexport const u8aConcat = (...u8as: Uint8Array[]): Uint8Array => {\n // Calculate the total length of the resulting Uint8Array\n const totalLength = u8as.reduce((sum, u8a) => sum + u8a.length, 0)\n\n // Create a new Uint8Array with the total length\n const result = new Uint8Array(totalLength)\n\n let offset = 0 // Initialize the offset for placing elements\n for (const u8a of u8as) {\n result.set(u8a, offset) // Set the current Uint8Array at the current offset\n offset += u8a.length // Update the offset for the next Uint8Array\n }\n\n return result\n}\n","/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { decodeAddress } from 'dedot/utils'\nimport type { RefObject } from 'react'\nimport { rmCommas, rmDecimals } from './base'\nimport type { AnyObject } from './types'\n\n/**\n * Converts an on-chain balance value from planck to a decimal value in token units.\n *\n * @function planckToUnit\n * @param {number | BigInt | string} val - The balance value in planck. Accepts a `number`, `BigInt`, or `string`.\n * @param {number} units - The number of decimal places in the token unit (10^units planck per 1 token).\n * @returns {string} The equivalent token unit value as a decimal string.\n * @example\n * // Convert 1500000000000 planck to tokens with 12 decimal places\n * planckToUnit(\"1500000000000\", 12); // returns \"1.5\"\n */\nexport const planckToUnit = (\n val: number | bigint | string,\n units: number\n): string => {\n try {\n // Ensure `units` is a positive integer.\n units = Math.max(Math.round(units), 0)\n\n // Convert `val` to BigInt based on its type\n const bigIntVal =\n typeof val === 'bigint'\n ? val\n : BigInt(\n typeof val === 'number'\n ? Math.floor(val).toString()\n : rmDecimals(rmCommas(val))\n )\n\n const divisor = units === 0 ? 1n : BigInt(10) ** BigInt(units)\n\n // Integer division and remainder for the fractional part\n const integerPart = bigIntVal / divisor\n const fractionalPart = bigIntVal % divisor\n\n // Format fractional part with leading zeros to maintain `units` decimal places\n const fractionalStr =\n units > 0 ? `.${fractionalPart.toString().padStart(units, '0')}` : ``\n\n // Combine integer and fractional parts as a decimal string\n return `${integerPart}${fractionalStr}`\n } catch (e) {\n return '0'\n }\n}\n\n/**\n * Converts a token unit value to an integer value in planck.\n *\n * @function unitToPlanck\n * @param {string | number | BigInt} val - The token unit value to convert. Accepts a string, number, or BigInt.\n * @param {number} units - The number of decimal places for conversion (10^units planck per 1 token).\n * @returns {BigInt} The equivalent value in planck as a BigInt.\n * @example\n * // Convert \"1.5\" tokens to planck with 12 decimal places\n * unitToPlanck(\"1.5\", 12); // returns BigInt(\"1500000000000\")\n */\nexport const unitToPlanck = (\n val: string | number | bigint,\n units: number\n): bigint => {\n try {\n // Ensure `units` is a positive integer.\n units = Math.max(Math.round(units), 0)\n\n // Convert `val` to a string; if empty or invalid, default to \"0\"\n const strVal =\n (typeof val === 'string' ? rmCommas(val) : val.toString()) || '0'\n\n // Split into integer and fractional parts\n const [integerPart, fractionalPart = ''] = strVal.split('.')\n\n // Process the integer part by converting to BigInt and scaling it to the given units\n let bigIntValue = BigInt(integerPart) * BigInt(10) ** BigInt(units)\n\n // Process the fractional part if it exists\n if (fractionalPart) {\n let fractionalValue: bigint\n\n if (fractionalPart.length > units) {\n // If fractional part exceeds units, truncate it\n fractionalValue = BigInt(fractionalPart.slice(0, units))\n } else {\n // Otherwise, pad the fractional part to match units\n fractionalValue = BigInt(fractionalPart.padEnd(units, '0'))\n }\n\n bigIntValue += fractionalValue\n }\n\n return bigIntValue\n } catch (e) {\n return BigInt(0)\n }\n}\n\n/**\n * @name remToUnit\n * @summary Converts a rem string to a number.\n */\nexport const remToUnit = (rem: string) =>\n Number(rem.slice(0, rem.length - 3)) *\n parseFloat(getComputedStyle(document.documentElement).fontSize)\n\n/**\n * @name capitalizeFirstLetter\n * @summary Capitalize the first letter of a string.\n */\nexport const capitalizeFirstLetter = (string: string) =>\n string.charAt(0).toUpperCase() + string.slice(1)\n\n/**\n * @name snakeToCamel\n * @summary converts a string from snake / kebab-case to camel-case.\n */\nexport const snakeToCamel = (str: string) =>\n str\n .toLowerCase()\n .replace(/([-_][a-z])/g, (group) =>\n group.toUpperCase().replace('-', '').replace('_', '')\n )\n\n/**\n * @name setStateWithRef\n * @summary Synchronize React state and its reference with the provided value.\n */\nexport const setStateWithRef = <T>(\n value: T,\n setState: (_state: T) => void,\n ref: RefObject<T>\n): void => {\n setState(value)\n ref.current = value\n}\n\n/**\n * @name localStorageOrDefault\n * @summary Retrieve the local stroage value with the key, return defult value if it is not\n * found.\n */\nexport const localStorageOrDefault = <T>(\n key: string,\n _default: T,\n parse = false\n): T | string => {\n const val: string | null = localStorage.getItem(key)\n\n if (val === null) {\n return _default\n }\n\n if (parse) {\n return JSON.parse(val) as T\n }\n return val\n}\n\n/**\n * @name isValidAddress\n * @summary Return whether an address is valid Substrate address.\n */\nexport const isValidAddress = (address: string): boolean => {\n try {\n decodeAddress(address)\n return true\n } catch (e) {\n return false\n }\n}\n\n/**\n * @name extractUrlValue\n * @summary Extracts a URL value from a URL string.\n */\nexport const extractUrlValue = (key: string, url?: string) => {\n if (typeof url === 'undefined') {\n url = window.location.href\n }\n const match = url.match(`[?&]${key}=([^&]+)`)\n return match ? match[1] : null\n}\n\n/**\n * @name varToUrlHash\n * @summary Puts a variable into the URL hash as a param.\n * @description\n * Since url variables are added to the hash and are not treated as URL params, the params are split\n * and parsed into a `URLSearchParams`.\n */\nexport const varToUrlHash = (\n key: string,\n val: string,\n addIfMissing: boolean\n) => {\n const hash = window.location.hash\n const [page, params] = hash.split('?')\n const searchParams = new URLSearchParams(params)\n\n if (searchParams.get(key) === null && !addIfMissing) {\n return\n }\n searchParams.set(key, val)\n window.location.hash = `${page}?${searchParams.toString()}`\n}\n\n/**\n * @name removeVarFromUrlHash\n * @summary\n * Removes a variable `key` from the URL hash if it exists. Removes dangling `?` if no URL variables\n * exist.\n */\nexport const removeVarFromUrlHash = (key: string) => {\n const hash = window.location.hash\n const [page, params] = hash.split('?')\n const searchParams = new URLSearchParams(params)\n if (searchParams.get(key) === null) {\n return\n }\n searchParams.delete(key)\n const paramsAsStr = searchParams.toString()\n window.location.hash = `${page}${paramsAsStr ? `?${paramsAsStr}` : ``}`\n}\n\n/**\n * @name sortWithNull\n * @summary Sorts an array with nulls last.\n */\nexport const sortWithNull =\n (ascending: boolean) => (a: unknown, b: unknown) => {\n // if both items are undefined, treat them as equal\n if (typeof a === 'undefined' && typeof b === 'undefined') {\n return 0\n }\n // if either item is undefined, sort it last\n if (typeof a === 'undefined' || typeof b === 'undefined') {\n return typeof a === 'undefined' ? 1 : -1\n }\n // equal items sort equally\n if (a === b) {\n return 0\n }\n // nulls sort after anything else\n if (a === null) {\n return 1\n }\n if (b === null) {\n return -1\n }\n // otherwise, if we're ascending, lowest sorts first\n if (ascending) {\n return a < b ? -1 : 1\n }\n // if descending, highest sorts first\n return a < b ? 1 : -1\n }\n\n/**\n * @name applyWidthAsPadding\n * @summary Applies width of subject to paddingRight of container.\n */\nexport const applyWidthAsPadding = (\n subjectRef: RefObject<HTMLDivElement | null>,\n containerRef: RefObject<HTMLDivElement | null>\n) => {\n if (containerRef.current && subjectRef.current) {\n containerRef.current.style.paddingRight = `${\n subjectRef.current.offsetWidth + remToUnit('1rem')\n }px`\n }\n}\n\n/**\n * @name unescape\n * @summary Replaces \\” with “\n */\nexport const unescape = (val: string) => val.replace(/\\\\\"/g, '\"')\n\n/**\n * @name inChrome\n * @summary Whether the application is rendering in Chrome.\n */\nexport const inChrome = () => {\n const isChromium = (window as Window & { chrome?: boolean })?.chrome || null\n const winNav = (window as Window)?.navigator || null\n const isOpera =\n typeof (window as Window & { opr?: boolean })?.opr !== 'undefined'\n const isIEedge = winNav?.userAgent.indexOf('Edg') > -1 || false\n const isIOSChrome = winNav?.userAgent.match('CriOS') || false\n\n if (isIOSChrome) {\n return true\n }\n if (\n isChromium !== null &&\n typeof isChromium !== 'undefined' &&\n isOpera === false &&\n isIEedge === false\n ) {\n return true\n }\n return false\n}\n\n/**\n * @name addedTo\n * @summary Given 2 objects and some keys, return items in the fresh object that do not exist in the\n * stale object by matching the given common key values of both objects.\n */\nexport const addedTo = (\n fresh: AnyObject[],\n stale: AnyObject[],\n keys: string[]\n): AnyObject[] =>\n typeof fresh !== 'object' || typeof stale !== 'object' || !keys.length\n ? []\n : fresh.filter(\n (freshItem) =>\n !stale.find((staleItem) =>\n keys.every((key) =>\n !(key in staleItem) || !(key in freshItem)\n ? false\n : staleItem[key] === freshItem[key]\n )\n )\n )\n\n/**\n * @name removedFrom\n * @summary Given 2 objects and some keys, return items in the stale object that do not exist in the\n * fresh object by matching the given common key values of both objects.\n */\nexport const removedFrom = (\n fresh: AnyObject[],\n stale: AnyObject[],\n keys: string[]\n): AnyObject[] =>\n typeof fresh !== 'object' || typeof stale !== 'object' || !keys.length\n ? []\n : stale.filter(\n (staleItem) =>\n !fresh.find((freshItem) =>\n keys.every((key) =>\n !(key in staleItem) || !(key in freshItem)\n ? false\n : freshItem[key] === staleItem[key]\n )\n )\n )\n\n/**\n * @name matchedProperties\n * @summary Given 2 objects and some keys, return items in object 1 that also exist in object 2 by\n * matching the given common key values of both objects.\n */\nexport const matchedProperties = (\n objX: AnyObject[],\n objY: AnyObject[],\n keys: string[]\n): AnyObject[] =>\n typeof objX !== 'object' || typeof objY !== 'object' || !keys.length\n ? []\n : objY.filter((x) =>\n objX.find((y) =>\n keys.every((key) =>\n !(key in x) || !(key in y) ? false : y[key] === x[key]\n )\n )\n )\n\n/**\n * @name isValidHttpUrl\n * @summary Give a string, return whether it is a valid http URL.\n * @param string - The string to check.\n */\nexport const isValidHttpUrl = (string: string) => {\n let url: URL\n try {\n url = new URL(string)\n } catch (_) {\n return false\n }\n return url.protocol === 'http:' || url.protocol === 'https:'\n}\n\n/**\n * @name makeCancelable\n * @summary Makes a promise cancellable.\n * @param promise - The promise to make cancellable.\n */\nexport const makeCancelable = (promise: Promise<AnyObject>) => {\n let hasCanceled = false\n\n const wrappedPromise = new Promise((resolve, reject) => {\n promise.then((val) =>\n hasCanceled ? reject(Error('Cancelled')) : resolve(val)\n )\n promise.catch((error) =>\n hasCanceled ? reject(Error('Cancelled')) : reject(error)\n )\n })\n\n return {\n promise: wrappedPromise,\n cancel: () => {\n hasCanceled = true\n },\n }\n}\n\n/**\n * @name unimplemented\n * @summary A placeholder function to signal a deliberate unimplementation.\n * Consumes an arbitrary number of props.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const unimplemented = ({ ...props }) => {\n /* unimplemented */\n}\n\n/**\n * Deep merge two objects.\n * @param target\n * @param ...sources\n */\n\nexport const mergeDeep = (\n target: AnyObject,\n ...sources: AnyObject[]\n): AnyObject => {\n if (!sources.length) {\n return target\n }\n\n const isObject = (item: AnyObject) =>\n item && typeof item === 'object' && !Array.isArray(item)\n const source = sources.shift()\n\n if (isObject(target) && isObject(source)) {\n for (const key in source) {\n if (isObject(source[key])) {\n if (!target[key]) {\n Object.assign(target, { [key]: {} })\n }\n mergeDeep(target[key], source[key])\n } else {\n Object.assign(target, { [key]: source[key] })\n }\n }\n }\n return mergeDeep(target, ...sources)\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/base.ts","../src/convert.ts","../src/unit.ts"],"sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { encodeAddress } from 'dedot/utils'\n\n/**\n * Ensures a number has at least the specified number of decimal places, retaining commas in the output if they are present in the input.\n *\n * @function minDecimalPlaces\n * @param {string | number | BigInt} val - The input number, which can be a `string` with or without commas, a `number`, or a `BigInt`.\n * @param {number} minDecimals - The minimum number of decimal places to enforce.\n * @returns {string} The formatted number as a string, padded with zeros if needed to meet `minDecimals`, retaining commas if originally provided.\n * If `val` is invalid, returns \"0\".\n * @example\n * // Pads \"1,234.5\" to have at least 3 decimal places, with commas\n * minDecimalPlaces(\"1,234.5\", 3); // returns \"1,234.500\"\n *\n * // Returns \"1234.56\" unchanged\n * minDecimalPlaces(1234.56, 2); // returns \"1234.56\"\n *\n * // Pads BigInt 1234 with 2 decimals\n * minDecimalPlaces(BigInt(1234), 2); // returns \"1234.00\"\n */\nexport const minDecimalPlaces = (\n\tval: string | number | bigint,\n\tminDecimals: number,\n): string => {\n\ttry {\n\t\t// Determine if we should retain commas based on original input type\n\t\tconst retainCommas = typeof val === 'string' && val.includes(',')\n\n\t\t// Convert `val` to a plain string for processing\n\t\tconst strVal =\n\t\t\ttypeof val === 'string' ? val.replace(/,/g, '') : val.toString()\n\n\t\t// Separate integer and decimal parts\n\t\tconst [integerPart, fractionalPart = ''] = strVal.split('.')\n\n\t\t// Parse the integer part as a BigInt\n\t\tconst whole = BigInt(integerPart || '0')\n\n\t\t// Calculate missing decimal places\n\t\tconst missingDecimals = minDecimals - fractionalPart.length\n\n\t\t// Format the integer part back with commas only if the input had commas\n\t\tconst formattedWhole = retainCommas\n\t\t\t? Intl.NumberFormat('en-US').format(whole)\n\t\t\t: whole.toString()\n\n\t\t// If missing decimals are needed, pad with zeros; otherwise, return the original value\n\t\treturn missingDecimals > 0\n\t\t\t? `${formattedWhole}.${fractionalPart}${'0'.repeat(missingDecimals)}`\n\t\t\t: `${formattedWhole}.${fractionalPart}`\n\t} catch {\n\t\t// The provided value is not a valid number, return \"0\".\n\t\treturn '0'\n\t}\n}\n\n/**\n * @name camelize\n * @summary Converts a string of text to camelCase.\n */\nexport const camelize = (str: string) => {\n\tconst convertToString = (string: string) => {\n\t\tif (string) {\n\t\t\tif (typeof string === 'string') {\n\t\t\t\treturn string\n\t\t\t}\n\t\t\treturn String(string)\n\t\t}\n\t\treturn ''\n\t}\n\n\tconst toWords = (inp: string) =>\n\t\tconvertToString(inp).match(\n\t\t\t/[A-Z\\xC0-\\xD6\\xD8-\\xDE]?[a-z\\xDF-\\xF6\\xF8-\\xFF]+|[A-Z\\xC0-\\xD6\\xD8-\\xDE]+(?![a-z\\xDF-\\xF6\\xF8-\\xFF])|\\d+/g,\n\t\t)\n\n\tconst simpleCamelCase = (inp: string[]) => {\n\t\tlet result = ''\n\t\tfor (let i = 0; i < inp?.length; i++) {\n\t\t\tconst currString = inp[i]\n\t\t\tlet tmpStr = currString.toLowerCase()\n\t\t\tif (i !== 0) {\n\t\t\t\ttmpStr =\n\t\t\t\t\ttmpStr.slice(0, 1).toUpperCase() + tmpStr.slice(1, tmpStr.length)\n\t\t\t}\n\t\t\tresult += tmpStr\n\t\t}\n\t\treturn result\n\t}\n\n\tconst w = toWords(str)?.map((a) => a.toLowerCase())\n\treturn simpleCamelCase(w || [])\n}\n\n/**\n * @name ellipsisFn\n * @summary Receives an address and creates ellipsis on the given string, based on parameters.\n * @param str - The string to apply the ellipsis on\n * @param amount - The amount of characters that the ellipsis will be\n * @param position - where the ellipsis will apply; if center the amount of character is the\n * same for beginning and end; if \"start\" or \"end\" then its only once the amount; defaults to \"start\"\n */\nexport const ellipsisFn = (\n\tstr: string,\n\tamount = 6,\n\tposition: 'start' | 'end' | 'center' = 'center',\n) => {\n\tconst half = str.length / 2\n\n\t// having an amount less than 4 is a bit extreme so we default there\n\tif (amount <= 4) {\n\t\tif (position === 'center') {\n\t\t\treturn str.slice(0, 4) + '...' + str.slice(-4)\n\t\t}\n\t\tif (position === 'end') {\n\t\t\treturn str.slice(0, 4) + '...'\n\t\t}\n\t\treturn '...' + str.slice(-4)\n\t}\n\t// if the amount requested is in a \"logical\" amount - meaning that it can display the address\n\t// without repeating the same information twice - then go for it;\n\tif (position === 'center') {\n\t\treturn amount >= (str.length - 2) / 2\n\t\t\t? str.slice(0, half - 3) + '...' + str.slice(-(half - 3))\n\t\t\t: str.slice(0, amount) + '...' + str.slice(-amount)\n\t}\n\t// else, the user has been mistaskenly extreme, so just show the maximum possible amount\n\tif (amount >= str.length) {\n\t\tif (position === 'end') {\n\t\t\treturn str.slice(0, str.length - 3) + '...'\n\t\t}\n\t\treturn '...' + str.slice(-(str.length - 3))\n\t} else {\n\t\tif (position === 'end') {\n\t\t\treturn str.slice(0, amount) + '...'\n\t\t}\n\t\treturn '...' + str.slice(amount)\n\t}\n}\n\n/**\n * @name pageFromUri\n * @summary Use url variables to load the default components upon the first page visit.\n */\nexport const pageFromUri = (pathname: string, fallback: string) => {\n\tconst lastUriItem = pathname.substring(pathname.lastIndexOf('/') + 1)\n\tconst page = lastUriItem.trim() === '' ? fallback : lastUriItem\n\treturn page.trim()\n}\n\n/**\n * @name rmCommas\n * @summary Removes the commas from a string.\n */\nexport const rmCommas = (val: string): string => val.replace(/,/g, '')\n\n/**\n * @name rmDecimals\n * @summary Removes the decimal point and decimals from a string.\n */\nexport const rmDecimals = (str: string) => str.split('.')[0]\n\n/**\n * @name shuffle\n * @summary Shuffle a set of objects.\n */\nexport const shuffle = <T>(array: T[]) => {\n\tlet currentIndex = array.length\n\tlet randomIndex\n\twhile (currentIndex !== 0) {\n\t\trandomIndex = Math.floor(Math.random() * currentIndex)\n\t\tcurrentIndex--\n\t\t;[array[currentIndex], array[randomIndex]] = [\n\t\t\tarray[randomIndex],\n\t\t\tarray[currentIndex],\n\t\t]\n\t}\n\treturn array\n}\n\n/**\n * @name withTimeout\n * @summary Timeout a promise after a specified number of milliseconds.\n */\nexport const withTimeout = (\n\tms: number,\n\tpromise: Promise<unknown>,\n\toptions?: {\n\t\tonTimeout?: () => void\n\t},\n) => {\n\tconst timeout = new Promise((resolve) =>\n\t\tsetTimeout(async () => {\n\t\t\tif (typeof options?.onTimeout === 'function') {\n\t\t\t\toptions.onTimeout()\n\t\t\t}\n\t\t\tresolve(undefined)\n\t\t}, ms),\n\t)\n\treturn Promise.race([promise, timeout])\n}\n\n/**\n * @name withTimeoutThrow\n * @summary Timeout a promise after a specified number of milliseconds by throwing an error\n */\nexport const withTimeoutThrow = <T>(\n\tms: number,\n\tpromise: Promise<T>,\n\toptions?: {\n\t\tonTimeout?: () => void\n\t},\n) => {\n\tconst timeout = new Promise((reject) =>\n\t\tsetTimeout(async () => {\n\t\t\tif (typeof options?.onTimeout === 'function') {\n\t\t\t\toptions.onTimeout()\n\t\t\t}\n\t\t\treject('Function timeout')\n\t\t}, ms),\n\t)\n\treturn Promise.race([promise, timeout])\n}\n\n/**\n * @name appendOrEmpty\n * @summary Returns ` value` if a condition is truthy, or an empty string otherwise.\n */\nexport const appendOrEmpty = (\n\tcondition: boolean | string | undefined,\n\tvalue: string,\n) => (condition ? ` ${value}` : '')\n\n/**\n * @name appendOr\n * @summary Returns ` value` if condition is truthy, or ` fallback` otherwise.\n */\nexport const appendOr = (\n\tcondition: boolean | string | undefined,\n\tvalue: string,\n\tfallback: string,\n) => (condition ? ` ${value}` : ` ${fallback}`)\n\n/**\n * @name formatAccountSs58\n * @summary Formats an address with the supplied ss58 prefix, or returns null if invalid.\n */\nexport const formatAccountSs58 = (\n\taddress: string,\n\tss58: number,\n): string | null => {\n\ttry {\n\t\treturn encodeAddress(address, ss58)\n\t} catch {\n\t\treturn null\n\t}\n}\n\n/**\n * @name tryFormatSs58\n * @summary Formats an address with the supplied ss58 prefix, or returns the original address if\n * invalid.\n */\nexport const tryFormatSs58 = (address: string, ss58: number): string => {\n\ttry {\n\t\treturn encodeAddress(address, ss58)\n\t} catch {\n\t\treturn address\n\t}\n}\n\n/**\n * @name removeHexPrefix\n * @summary Takes a string str as input and returns a new string with the \"0x\" prefix removed if it\n * exists at the beginning of the input string.\n */\nexport const removeHexPrefix = (str: string): string => str.replace(/^0x/, '')\n\n// Check if 2 sets contain the same elements.\n// biome-ignore lint/suspicious/noExplicitAny: <>\nexport const eqSet = (xs: Set<any>, ys: Set<any>) =>\n\txs.size === ys.size && [...xs].every((x) => ys.has(x))\n\n// Check if one set contains all the elements of another set.\n// biome-ignore lint/suspicious/noExplicitAny: <>\nexport const isSuperset = (set: Set<any>, subset: Set<any>) => {\n\tfor (const elem of subset) {\n\t\tif (!set.has(elem)) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n/**\n * Finds the maximum value among a list of BigInt values.\n *\n * @function maxBigInt\n * @param {...bigint} values - A list of BigInt values to compare.\n * @returns {bigint} The largest BigInt value in the provided list.\n * @example\n * // Returns the maximum BigInt value\n * maxBigInt(10n, 50n, 30n, 100n, 20n); // 100n\n */\nexport const maxBigInt = (...values: bigint[]): bigint =>\n\tvalues.reduce((max, current) => (current > max ? current : max))\n\n/**\n * Finds the minimum value among a list of BigInt values.\n *\n * @function minBigInt\n * @param {...bigint} values - A list of BigInt values to compare.\n * @returns {bigint} The smallest BigInt value in the provided list.\n * @example\n * // Returns the minimum BigInt value\n * minBigInt(10n, 50n, 30n, 100n, 20n); // 10n\n */\nexport const minBigInt = (...values: bigint[]): bigint =>\n\tvalues.reduce((min, current) => (current < min ? current : min))\n","// /* @license Copyright 2024 w3ux authors & contributors\n// SPDX-License-Identifier: GPL-3.0-only */\n\n/**\n * Concatenates multiple Uint8Array instances into a single Uint8Array.\n *\n * @param {Uint8Array[]} u8as - An array of Uint8Array instances to concatenate.\n * @returns {Uint8Array} A new Uint8Array containing all the input arrays concatenated.\n */\nexport const u8aConcat = (...u8as: Uint8Array[]): Uint8Array => {\n\t// Calculate the total length of the resulting Uint8Array\n\tconst totalLength = u8as.reduce((sum, u8a) => sum + u8a.length, 0)\n\n\t// Create a new Uint8Array with the total length\n\tconst result = new Uint8Array(totalLength)\n\n\tlet offset = 0 // Initialize the offset for placing elements\n\tfor (const u8a of u8as) {\n\t\tresult.set(u8a, offset) // Set the current Uint8Array at the current offset\n\t\toffset += u8a.length // Update the offset for the next Uint8Array\n\t}\n\n\treturn result\n}\n","/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { decodeAddress } from 'dedot/utils'\nimport type { RefObject } from 'react'\nimport { rmCommas, rmDecimals } from './base'\nimport type { AnyObject } from './types'\n\n/**\n * Converts an on-chain balance value from planck to a decimal value in token units.\n *\n * @function planckToUnit\n * @param {number | BigInt | string} val - The balance value in planck. Accepts a `number`, `BigInt`, or `string`.\n * @param {number} units - The number of decimal places in the token unit (10^units planck per 1 token).\n * @returns {string} The equivalent token unit value as a decimal string.\n * @example\n * // Convert 1500000000000 planck to tokens with 12 decimal places\n * planckToUnit(\"1500000000000\", 12); // returns \"1.5\"\n */\nexport const planckToUnit = (\n\tval: number | bigint | string,\n\tunits: number,\n): string => {\n\ttry {\n\t\t// Ensure `units` is a positive integer.\n\t\tunits = Math.max(Math.round(units), 0)\n\n\t\t// Convert `val` to BigInt based on its type\n\t\tconst bigIntVal =\n\t\t\ttypeof val === 'bigint'\n\t\t\t\t? val\n\t\t\t\t: BigInt(\n\t\t\t\t\t\ttypeof val === 'number'\n\t\t\t\t\t\t\t? Math.floor(val).toString()\n\t\t\t\t\t\t\t: rmDecimals(rmCommas(val)),\n\t\t\t\t\t)\n\n\t\tconst divisor = units === 0 ? 1n : BigInt(10) ** BigInt(units)\n\n\t\t// Integer division and remainder for the fractional part\n\t\tconst integerPart = bigIntVal / divisor\n\t\tconst fractionalPart = bigIntVal % divisor\n\n\t\t// Format fractional part with leading zeros to maintain `units` decimal places\n\t\tconst fractionalStr =\n\t\t\tunits > 0 ? `.${fractionalPart.toString().padStart(units, '0')}` : ``\n\n\t\t// Combine integer and fractional parts as a decimal string\n\t\treturn `${integerPart}${fractionalStr}`\n\t} catch {\n\t\treturn '0'\n\t}\n}\n\n/**\n * Converts a token unit value to an integer value in planck.\n *\n * @function unitToPlanck\n * @param {string | number | BigInt} val - The token unit value to convert. Accepts a string, number, or BigInt.\n * @param {number} units - The number of decimal places for conversion (10^units planck per 1 token).\n * @returns {BigInt} The equivalent value in planck as a BigInt.\n * @example\n * // Convert \"1.5\" tokens to planck with 12 decimal places\n * unitToPlanck(\"1.5\", 12); // returns BigInt(\"1500000000000\")\n */\nexport const unitToPlanck = (\n\tval: string | number | bigint,\n\tunits: number,\n): bigint => {\n\ttry {\n\t\t// Ensure `units` is a positive integer.\n\t\tunits = Math.max(Math.round(units), 0)\n\n\t\t// Convert `val` to a string; if empty or invalid, default to \"0\"\n\t\tconst strVal =\n\t\t\t(typeof val === 'string' ? rmCommas(val) : val.toString()) || '0'\n\n\t\t// Split into integer and fractional parts\n\t\tconst [integerPart, fractionalPart = ''] = strVal.split('.')\n\n\t\t// Process the integer part by converting to BigInt and scaling it to the given units\n\t\tlet bigIntValue = BigInt(integerPart) * BigInt(10) ** BigInt(units)\n\n\t\t// Process the fractional part if it exists\n\t\tif (fractionalPart) {\n\t\t\tlet fractionalValue: bigint\n\n\t\t\tif (fractionalPart.length > units) {\n\t\t\t\t// If fractional part exceeds units, truncate it\n\t\t\t\tfractionalValue = BigInt(fractionalPart.slice(0, units))\n\t\t\t} else {\n\t\t\t\t// Otherwise, pad the fractional part to match units\n\t\t\t\tfractionalValue = BigInt(fractionalPart.padEnd(units, '0'))\n\t\t\t}\n\n\t\t\tbigIntValue += fractionalValue\n\t\t}\n\n\t\treturn bigIntValue\n\t} catch {\n\t\treturn BigInt(0)\n\t}\n}\n\n/**\n * @name remToUnit\n * @summary Converts a rem string to a number.\n */\nexport const remToUnit = (rem: string) =>\n\tNumber(rem.slice(0, rem.length - 3)) *\n\tparseFloat(getComputedStyle(document.documentElement).fontSize)\n\n/**\n * @name capitalizeFirstLetter\n * @summary Capitalize the first letter of a string.\n */\nexport const capitalizeFirstLetter = (string: string) =>\n\tstring.charAt(0).toUpperCase() + string.slice(1)\n\n/**\n * @name snakeToCamel\n * @summary converts a string from snake / kebab-case to camel-case.\n */\nexport const snakeToCamel = (str: string) =>\n\tstr\n\t\t.toLowerCase()\n\t\t.replace(/([-_][a-z])/g, (group) =>\n\t\t\tgroup.toUpperCase().replace('-', '').replace('_', ''),\n\t\t)\n\n/**\n * @name setStateWithRef\n * @summary Synchronize React state and its reference with the provided value.\n */\nexport const setStateWithRef = <T>(\n\tvalue: T,\n\tsetState: (_state: T) => void,\n\tref: RefObject<T>,\n): void => {\n\tsetState(value)\n\tref.current = value\n}\n\n/**\n * @name localStorageOrDefault\n * @summary Retrieve the local stroage value with the key, return defult value if it is not\n * found.\n */\nexport const localStorageOrDefault = <T>(\n\tkey: string,\n\t_default: T,\n\tparse = false,\n): T | string => {\n\tconst val: string | null = localStorage.getItem(key)\n\n\tif (val === null) {\n\t\treturn _default\n\t}\n\n\tif (parse) {\n\t\treturn JSON.parse(val) as T\n\t}\n\treturn val\n}\n\n/**\n * @name isValidAddress\n * @summary Return whether an address is valid Substrate address.\n */\nexport const isValidAddress = (address: string): boolean => {\n\ttry {\n\t\tdecodeAddress(address)\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * @name extractUrlValue\n * @summary Extracts a URL value from a URL string.\n */\nexport const extractUrlValue = (key: string, url?: string) => {\n\tif (typeof url === 'undefined') {\n\t\turl = window.location.href\n\t}\n\tconst match = url.match(`[?&]${key}=([^&]+)`)\n\treturn match ? match[1] : null\n}\n\n/**\n * @name varToUrlHash\n * @summary Puts a variable into the URL hash as a param.\n * @description\n * Since url variables are added to the hash and are not treated as URL params, the params are split\n * and parsed into a `URLSearchParams`.\n */\nexport const varToUrlHash = (\n\tkey: string,\n\tval: string,\n\taddIfMissing: boolean,\n) => {\n\tconst hash = window.location.hash\n\tconst [page, params] = hash.split('?')\n\tconst searchParams = new URLSearchParams(params)\n\n\tif (searchParams.get(key) === null && !addIfMissing) {\n\t\treturn\n\t}\n\tsearchParams.set(key, val)\n\twindow.location.hash = `${page}?${searchParams.toString()}`\n}\n\n/**\n * @name removeVarFromUrlHash\n * @summary\n * Removes a variable `key` from the URL hash if it exists. Removes dangling `?` if no URL variables\n * exist.\n */\nexport const removeVarFromUrlHash = (key: string) => {\n\tconst hash = window.location.hash\n\tconst [page, params] = hash.split('?')\n\tconst searchParams = new URLSearchParams(params)\n\tif (searchParams.get(key) === null) {\n\t\treturn\n\t}\n\tsearchParams.delete(key)\n\tconst paramsAsStr = searchParams.toString()\n\twindow.location.hash = `${page}${paramsAsStr ? `?${paramsAsStr}` : ``}`\n}\n\n/**\n * @name sortWithNull\n * @summary Sorts an array with nulls last.\n */\nexport const sortWithNull =\n\t(ascending: boolean) => (a: unknown, b: unknown) => {\n\t\t// if both items are undefined, treat them as equal\n\t\tif (typeof a === 'undefined' && typeof b === 'undefined') {\n\t\t\treturn 0\n\t\t}\n\t\t// if either item is undefined, sort it last\n\t\tif (typeof a === 'undefined' || typeof b === 'undefined') {\n\t\t\treturn typeof a === 'undefined' ? 1 : -1\n\t\t}\n\t\t// equal items sort equally\n\t\tif (a === b) {\n\t\t\treturn 0\n\t\t}\n\t\t// nulls sort after anything else\n\t\tif (a === null) {\n\t\t\treturn 1\n\t\t}\n\t\tif (b === null) {\n\t\t\treturn -1\n\t\t}\n\t\t// otherwise, if we're ascending, lowest sorts first\n\t\tif (ascending) {\n\t\t\treturn a < b ? -1 : 1\n\t\t}\n\t\t// if descending, highest sorts first\n\t\treturn a < b ? 1 : -1\n\t}\n\n/**\n * @name applyWidthAsPadding\n * @summary Applies width of subject to paddingRight of container.\n */\nexport const applyWidthAsPadding = (\n\tsubjectRef: RefObject<HTMLDivElement | null>,\n\tcontainerRef: RefObject<HTMLDivElement | null>,\n) => {\n\tif (containerRef.current && subjectRef.current) {\n\t\tcontainerRef.current.style.paddingRight = `${\n\t\t\tsubjectRef.current.offsetWidth + remToUnit('1rem')\n\t\t}px`\n\t}\n}\n\n/**\n * @name unescape\n * @summary Replaces \\” with “\n */\nexport const unescape = (val: string) => val.replace(/\\\\\"/g, '\"')\n\n/**\n * @name inChrome\n * @summary Whether the application is rendering in Chrome.\n */\nexport const inChrome = () => {\n\tconst isChromium = (window as Window & { chrome?: boolean })?.chrome || null\n\tconst winNav = (window as Window)?.navigator || null\n\tconst isOpera =\n\t\ttypeof (window as Window & { opr?: boolean })?.opr !== 'undefined'\n\tconst isIEedge = winNav?.userAgent.indexOf('Edg') > -1 || false\n\tconst isIOSChrome = winNav?.userAgent.match('CriOS') || false\n\n\tif (isIOSChrome) {\n\t\treturn true\n\t}\n\tif (\n\t\tisChromium !== null &&\n\t\ttypeof isChromium !== 'undefined' &&\n\t\tisOpera === false &&\n\t\tisIEedge === false\n\t) {\n\t\treturn true\n\t}\n\treturn false\n}\n\n/**\n * @name addedTo\n * @summary Given 2 objects and some keys, return items in the fresh object that do not exist in the\n * stale object by matching the given common key values of both objects.\n */\nexport const addedTo = (\n\tfresh: AnyObject[],\n\tstale: AnyObject[],\n\tkeys: string[],\n): AnyObject[] =>\n\ttypeof fresh !== 'object' || typeof stale !== 'object' || !keys.length\n\t\t? []\n\t\t: fresh.filter(\n\t\t\t\t(freshItem) =>\n\t\t\t\t\t!stale.find((staleItem) =>\n\t\t\t\t\t\tkeys.every((key) =>\n\t\t\t\t\t\t\t!(key in staleItem) || !(key in freshItem)\n\t\t\t\t\t\t\t\t? false\n\t\t\t\t\t\t\t\t: staleItem[key] === freshItem[key],\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t)\n\n/**\n * @name removedFrom\n * @summary Given 2 objects and some keys, return items in the stale object that do not exist in the\n * fresh object by matching the given common key values of both objects.\n */\nexport const removedFrom = (\n\tfresh: AnyObject[],\n\tstale: AnyObject[],\n\tkeys: string[],\n): AnyObject[] =>\n\ttypeof fresh !== 'object' || typeof stale !== 'object' || !keys.length\n\t\t? []\n\t\t: stale.filter(\n\t\t\t\t(staleItem) =>\n\t\t\t\t\t!fresh.find((freshItem) =>\n\t\t\t\t\t\tkeys.every((key) =>\n\t\t\t\t\t\t\t!(key in staleItem) || !(key in freshItem)\n\t\t\t\t\t\t\t\t? false\n\t\t\t\t\t\t\t\t: freshItem[key] === staleItem[key],\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t)\n\n/**\n * @name matchedProperties\n * @summary Given 2 objects and some keys, return items in object 1 that also exist in object 2 by\n * matching the given common key values of both objects.\n */\nexport const matchedProperties = (\n\tobjX: AnyObject[],\n\tobjY: AnyObject[],\n\tkeys: string[],\n): AnyObject[] =>\n\ttypeof objX !== 'object' || typeof objY !== 'object' || !keys.length\n\t\t? []\n\t\t: objY.filter((x) =>\n\t\t\t\tobjX.find((y) =>\n\t\t\t\t\tkeys.every((key) =>\n\t\t\t\t\t\t!(key in x) || !(key in y) ? false : y[key] === x[key],\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\n/**\n * @name isValidHttpUrl\n * @summary Give a string, return whether it is a valid http URL.\n * @param string - The string to check.\n */\nexport const isValidHttpUrl = (string: string) => {\n\tlet url: URL\n\ttry {\n\t\turl = new URL(string)\n\t} catch (_) {\n\t\treturn false\n\t}\n\treturn url.protocol === 'http:' || url.protocol === 'https:'\n}\n\n/**\n * @name makeCancelable\n * @summary Makes a promise cancellable.\n * @param promise - The promise to make cancellable.\n */\nexport const makeCancelable = (promise: Promise<AnyObject>) => {\n\tlet hasCanceled = false\n\n\tconst wrappedPromise = new Promise((resolve, reject) => {\n\t\tpromise.then((val) =>\n\t\t\thasCanceled ? reject(Error('Cancelled')) : resolve(val),\n\t\t)\n\t\tpromise.catch((error) =>\n\t\t\thasCanceled ? reject(Error('Cancelled')) : reject(error),\n\t\t)\n\t})\n\n\treturn {\n\t\tpromise: wrappedPromise,\n\t\tcancel: () => {\n\t\t\thasCanceled = true\n\t\t},\n\t}\n}\n\n/**\n * @name unimplemented\n * @summary A placeholder function to signal a deliberate unimplementation.\n * Consumes an arbitrary number of props.\n */\nexport const unimplemented = (_props?: unknown) => {\n\t/* unimplemented */\n}\n\n/**\n * Deep merge two objects.\n * @param target\n * @param ...sources\n */\n\nexport const mergeDeep = (\n\ttarget: AnyObject,\n\t...sources: AnyObject[]\n): AnyObject => {\n\tif (!sources.length) {\n\t\treturn target\n\t}\n\n\tconst isObject = (item: AnyObject) =>\n\t\titem && typeof item === 'object' && !Array.isArray(item)\n\tconst source = sources.shift()\n\n\tif (isObject(target) && isObject(source)) {\n\t\tfor (const key in source) {\n\t\t\tif (isObject(source[key])) {\n\t\t\t\tif (!target[key]) {\n\t\t\t\t\tObject.assign(target, { [key]: {} })\n\t\t\t\t}\n\t\t\t\tmergeDeep(target[key], source[key])\n\t\t\t} else {\n\t\t\t\tObject.assign(target, { [key]: source[key] })\n\t\t\t}\n\t\t}\n\t}\n\treturn mergeDeep(target, ...sources)\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@w3ux/utils",
3
- "version": "2.2.3",
3
+ "version": "2.3.1",
4
4
  "license": "GPL-3.0-only",
5
5
  "type": "module",
6
6
  "description": "A collection of reusable utilities for manipulating data",
@@ -28,6 +28,6 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "dedot": "^0.13.1"
31
+ "dedot": "1.0.1"
32
32
  }
33
33
  }