mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-19 19:55:51 +00:00
feat: remove lodash as a dependency (#2378)
This will reduce the bundle size by ~23%(117kb). Only 4 methods were used `flatten`, `flatMap`, `omitBy`, and `groupBy`. `omitBy and `groupBy` were recreated while the es2019 implementations of `flatten` and `flatMap` are used. `lodash` is still used in the tests which is fine because it makes the tests cleaner. Closes #2118
This commit is contained in:
@@ -27,7 +27,6 @@
|
||||
"bip32": "^2.0.6",
|
||||
"bip39": "^3.0.4",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"lodash": "^4.17.4",
|
||||
"ripple-address-codec": "^4.3.1",
|
||||
"ripple-binary-codec": "^1.11.0",
|
||||
"ripple-keypairs": "^1.3.1",
|
||||
@@ -45,6 +44,7 @@
|
||||
"karma-chrome-launcher": "^3.1.1",
|
||||
"karma-jasmine": "^5.1.0",
|
||||
"karma-webpack": "^5.0.0",
|
||||
"lodash": "^4.17.4",
|
||||
"node-polyfill-webpack-plugin": "^2.0.1",
|
||||
"react": "^18.2.0",
|
||||
"typedoc": "0.25.0"
|
||||
@@ -58,7 +58,7 @@
|
||||
"build:lib": "tsc --build tsconfig.build.json",
|
||||
"build:web": "webpack",
|
||||
"build:browserTests": "webpack --config ./test/webpack.config.js",
|
||||
"analyze": "run-s build:web --analyze",
|
||||
"analyze": "webpack --analyze",
|
||||
"watch": "run-s build:lib --watch",
|
||||
"clean": "rm -rf dist build coverage",
|
||||
"docgen": "tsc --build tsconfig.docs.json && typedoc && echo js.xrpl.org >> ../../docs/CNAME",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import BigNumber from 'bignumber.js'
|
||||
import { fromSeed } from 'bip32'
|
||||
import { mnemonicToSeedSync, validateMnemonic } from 'bip39'
|
||||
import omitBy from 'lodash/omitBy'
|
||||
import {
|
||||
classicAddressToXAddress,
|
||||
isValidXAddress,
|
||||
@@ -26,6 +25,7 @@ import ECDSA from '../ECDSA'
|
||||
import { ValidationError } from '../errors'
|
||||
import { Transaction, validate } from '../models/transactions'
|
||||
import { ensureClassicAddress } from '../sugar/utils'
|
||||
import { omitBy } from '../utils/collections'
|
||||
import { hashSignedTx } from '../utils/hashes/hashLedger'
|
||||
|
||||
import { rfc1751MnemonicToKey } from './rfc1751'
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { BigNumber } from 'bignumber.js'
|
||||
import { flatMap } from 'lodash'
|
||||
import { decodeAccountID } from 'ripple-address-codec'
|
||||
import {
|
||||
decode,
|
||||
@@ -128,10 +127,9 @@ function getTransactionWithAllSigners(
|
||||
transactions: Transaction[],
|
||||
): Transaction {
|
||||
// Signers must be sorted in the combined transaction - See compareSigners' documentation for more details
|
||||
const sortedSigners: Signer[] = flatMap(
|
||||
transactions,
|
||||
(tx) => tx.Signers ?? [],
|
||||
).sort(compareSigners)
|
||||
const sortedSigners: Signer[] = transactions
|
||||
.flatMap((tx) => tx.Signers ?? [])
|
||||
.sort(compareSigners)
|
||||
|
||||
return { ...transactions[0], Signers: sortedSigners }
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import { EventEmitter } from 'events'
|
||||
import { Agent } from 'http'
|
||||
|
||||
import omitBy from 'lodash/omitBy'
|
||||
import WebSocket from 'ws'
|
||||
|
||||
import {
|
||||
@@ -12,6 +11,7 @@ import {
|
||||
XrplError,
|
||||
} from '../errors'
|
||||
import { BaseRequest } from '../models/methods/baseMethod'
|
||||
import { omitBy } from '../utils/collections'
|
||||
|
||||
import ConnectionManager from './ConnectionManager'
|
||||
import ExponentialBackoff from './ExponentialBackoff'
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import flatMap from 'lodash/flatMap'
|
||||
|
||||
import type { Balance, Client } from '..'
|
||||
import {
|
||||
AccountLinesRequest,
|
||||
@@ -108,7 +106,7 @@ async function getBalances(
|
||||
// combine results
|
||||
await Promise.all([xrpPromise, linesPromise]).then(
|
||||
([xrpBalance, linesResponses]) => {
|
||||
const accountLinesBalance = flatMap(linesResponses, (response) =>
|
||||
const accountLinesBalance = linesResponses.flatMap((response) =>
|
||||
formatBalances(response.result.lines),
|
||||
)
|
||||
if (xrpBalance !== '') {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/* eslint-disable max-lines-per-function -- Needs to process orderbooks. */
|
||||
import BigNumber from 'bignumber.js'
|
||||
import flatMap from 'lodash/flatMap'
|
||||
|
||||
import type { Client } from '../client'
|
||||
import { ValidationError } from '../errors'
|
||||
@@ -10,6 +9,7 @@ import {
|
||||
BookOffer,
|
||||
BookOfferCurrency,
|
||||
BookOffersRequest,
|
||||
BookOffersResponse,
|
||||
} from '../models/methods/bookOffers'
|
||||
|
||||
const DEFAULT_LIMIT = 20
|
||||
@@ -112,17 +112,18 @@ async function getOrderbook(
|
||||
taker: options.taker ? options.taker : undefined,
|
||||
}
|
||||
// 2. Make Request
|
||||
const directOfferResults = await this.requestAll(request)
|
||||
const directOfferResults: BookOffersResponse[] = await this.requestAll(
|
||||
request,
|
||||
)
|
||||
request.taker_gets = currency1
|
||||
request.taker_pays = currency2
|
||||
const reverseOfferResults = await this.requestAll(request)
|
||||
// 3. Return Formatted Response
|
||||
const directOffers = flatMap(
|
||||
directOfferResults,
|
||||
(directOfferResult) => directOfferResult.result.offers,
|
||||
|
||||
const directOffers = directOfferResults.flatMap(
|
||||
(directOfferResult: BookOffersResponse) => directOfferResult.result.offers,
|
||||
)
|
||||
const reverseOffers = flatMap(
|
||||
reverseOfferResults,
|
||||
const reverseOffers = reverseOfferResults.flatMap(
|
||||
(reverseOfferResult) => reverseOfferResult.result.offers,
|
||||
)
|
||||
|
||||
|
||||
52
packages/xrpl/src/utils/collections.ts
Normal file
52
packages/xrpl/src/utils/collections.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
type ValueOf<T> = T[keyof T]
|
||||
|
||||
/**
|
||||
* Creates an object composed of keys generated from the results of running each element of collection thru iteratee.
|
||||
* The order of grouped values is determined by the order they occur in collection.
|
||||
* The corresponding value of each key is an array of elements responsible for generating the key.
|
||||
*
|
||||
* Similar to lodash's groupBy
|
||||
*
|
||||
* @param array - array to iterate over
|
||||
* @param iteratee - function that returns key of the group to place the item
|
||||
*
|
||||
* @returns a map of arrays
|
||||
*/
|
||||
export function groupBy<T>(
|
||||
array: T[],
|
||||
iteratee: (value: T, index: number, array: T[]) => string,
|
||||
): { [p: string]: T[] } {
|
||||
// eslint-disable-next-line max-params -- need all the params for the fallback
|
||||
return array.reduce<{ [key: string]: T[] }>(function predicate(
|
||||
acc,
|
||||
value,
|
||||
index,
|
||||
arrayReference,
|
||||
) {
|
||||
;(acc[iteratee(value, index, arrayReference)] ||= []).push(value)
|
||||
return acc
|
||||
},
|
||||
{})
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an object composed of the own and inherited enumerable string keyed properties of object that
|
||||
* predicate doesn't return truthy for.
|
||||
*
|
||||
* @param obj - Object to have properties removed.
|
||||
* @param predicate - function that returns whether the property should be removed from the obj.
|
||||
*
|
||||
* @returns object
|
||||
*/
|
||||
export function omitBy<T extends object>(
|
||||
obj: T,
|
||||
predicate: (objElement: ValueOf<T>, k: string | number | symbol) => boolean,
|
||||
): Partial<T> {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- We know the keys are properties of T
|
||||
const keys: Array<keyof T> = Object.keys(obj) as Array<keyof T>
|
||||
const keysToKeep = keys.filter((kb) => !predicate(obj[kb], kb))
|
||||
return keysToKeep.reduce((acc: Partial<T>, key: keyof T) => {
|
||||
acc[key] = obj[key]
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
import BigNumber from 'bignumber.js'
|
||||
import flatten from 'lodash/flatten'
|
||||
import groupBy from 'lodash/groupBy'
|
||||
|
||||
import {
|
||||
Amount,
|
||||
@@ -10,6 +8,7 @@ import {
|
||||
Node,
|
||||
} from '../models'
|
||||
|
||||
import { groupBy } from './collections'
|
||||
import { dropsToXrp } from './xrpConversion'
|
||||
|
||||
interface BalanceChange {
|
||||
@@ -182,5 +181,5 @@ export default function getBalanceChanges(
|
||||
}
|
||||
return []
|
||||
})
|
||||
return groupByAccount(flatten(quantities))
|
||||
return groupByAccount(quantities.flat())
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import flatMap from 'lodash/flatMap'
|
||||
import { decode } from 'ripple-binary-codec'
|
||||
|
||||
import { NFToken } from '../models/ledger/NFTokenPage'
|
||||
@@ -33,6 +32,7 @@ function ensureDecodedMeta(
|
||||
* @returns The NFTokenID for the minted NFT.
|
||||
* @throws if meta is not TransactionMetadata.
|
||||
*/
|
||||
// eslint-disable-next-line max-lines-per-function -- This function has a lot of documentation
|
||||
export default function getNFTokenID(
|
||||
meta: TransactionMetadata | string | undefined,
|
||||
): string | undefined {
|
||||
@@ -57,7 +57,6 @@ export default function getNFTokenID(
|
||||
* not changed. Thus why we add the additional condition to check
|
||||
* if the PreviousFields contains NFTokens
|
||||
*/
|
||||
|
||||
const affectedNodes = decodedMeta.AffectedNodes.filter((node) => {
|
||||
if (isCreatedNode(node)) {
|
||||
return node.CreatedNode.LedgerEntryType === 'NFTokenPage'
|
||||
@@ -72,25 +71,28 @@ export default function getNFTokenID(
|
||||
})
|
||||
/* eslint-disable @typescript-eslint/consistent-type-assertions -- Necessary for parsing metadata */
|
||||
const previousTokenIDSet = new Set(
|
||||
flatMap(affectedNodes, (node) => {
|
||||
const nftokens = isModifiedNode(node)
|
||||
? (node.ModifiedNode.PreviousFields?.NFTokens as NFToken[])
|
||||
: []
|
||||
return nftokens.map((token) => token.NFToken.NFTokenID)
|
||||
}).filter((id) => Boolean(id)),
|
||||
affectedNodes
|
||||
.flatMap((node) => {
|
||||
const nftokens = isModifiedNode(node)
|
||||
? (node.ModifiedNode.PreviousFields?.NFTokens as NFToken[])
|
||||
: []
|
||||
return nftokens.map((token) => token.NFToken.NFTokenID)
|
||||
})
|
||||
.filter((id) => Boolean(id)),
|
||||
)
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unnecessary-condition -- Cleaner to read */
|
||||
const finalTokenIDs = flatMap(affectedNodes, (node) =>
|
||||
(
|
||||
(((node as ModifiedNode).ModifiedNode?.FinalFields?.NFTokens ??
|
||||
(node as CreatedNode).CreatedNode?.NewFields?.NFTokens) as NFToken[]) ??
|
||||
[]
|
||||
).map((token) => token.NFToken.NFTokenID),
|
||||
).filter((nftokenID) => Boolean(nftokenID))
|
||||
const finalTokenIDs = affectedNodes
|
||||
.flatMap((node) =>
|
||||
(
|
||||
(((node as ModifiedNode).ModifiedNode?.FinalFields?.NFTokens ??
|
||||
(node as CreatedNode).CreatedNode?.NewFields
|
||||
?.NFTokens) as NFToken[]) ?? []
|
||||
).map((token) => token.NFToken.NFTokenID),
|
||||
)
|
||||
.filter((nftokenID) => Boolean(nftokenID))
|
||||
/* eslint-enable @typescript-eslint/consistent-type-assertions -- Necessary for parsing metadata */
|
||||
/* eslint-enable @typescript-eslint/no-unnecessary-condition -- Cleaner to read */
|
||||
|
||||
const nftokenID = finalTokenIDs.find((id) => !previousTokenIDSet.has(id))
|
||||
|
||||
return nftokenID
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"pretty": true,
|
||||
"target": "es6",
|
||||
"lib": ["es2019", "dom"],
|
||||
"outDir": "./dist/npm",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
|
||||
Reference in New Issue
Block a user