Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: remove lodash as a dependency #2378

Merged
merged 9 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
688 changes: 356 additions & 332 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/xrpl/jest.config.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = {
roots: [...base.roots, '<rootDir>/test'],
testMatch: ['<rootDir>/test/**/*.test.ts'],
testPathIgnorePatterns: [
'<rootDir>/node_modules/(?!lodash-es)',
'<rootDir>/test/integration',
'<rootDir>/test/fixtures',
],
Expand Down
4 changes: 2 additions & 2 deletions packages/xrpl/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"bip32": "^2.0.6",
"bip39": "^3.0.4",
"https-proxy-agent": "^5.0.0",
"lodash": "^4.17.4",
"lodash-es": "^4.17.4",
"ripple-address-codec": "^4.3.0",
"ripple-binary-codec": "^1.6.0",
"ripple-keypairs": "^1.3.0",
Expand Down Expand Up @@ -56,7 +56,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",
Expand Down
2 changes: 1 addition & 1 deletion packages/xrpl/src/Wallet/index.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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'
Expand Down
8 changes: 3 additions & 5 deletions packages/xrpl/src/Wallet/signer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { BigNumber } from 'bignumber.js'
import { flatMap } from 'lodash'
import { decodeAccountID } from 'ripple-address-codec'
import {
decode,
Expand Down Expand Up @@ -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 }
}
Expand Down
2 changes: 1 addition & 1 deletion packages/xrpl/src/client/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import { EventEmitter } from 'events'
import { Agent } from 'http'

import omitBy from 'lodash/omitBy'
import WebSocket from 'ws'

import {
Expand All @@ -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'
Expand Down
4 changes: 1 addition & 3 deletions packages/xrpl/src/sugar/balances.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import flatMap from 'lodash/flatMap'

import type { Balance, Client } from '..'
import {
AccountLinesRequest,
Expand Down Expand Up @@ -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 !== '') {
Expand Down
16 changes: 9 additions & 7 deletions packages/xrpl/src/sugar/getOrderbook.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -10,6 +9,7 @@ import {
BookOffer,
BookOfferCurrency,
BookOffersRequest,
BookOffersResponse,
} from '../models/methods/bookOffers'

const DEFAULT_LIMIT = 20
Expand Down Expand Up @@ -112,17 +112,19 @@ 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,
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const reverseOffers = reverseOfferResults.flatMap(
(reverseOfferResult) => reverseOfferResult.result.offers,
)

Expand Down
48 changes: 48 additions & 0 deletions packages/xrpl/src/utils/collections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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[] } {
return array.reduce<{ [key: string]: T[] }>(
(acc, value, index, arrayReference) => {
;(acc[iteratee(value, index, arrayReference)] ||= []).push(value)
ckniffen marked this conversation as resolved.
Show resolved Hide resolved
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
}, {})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add unit tests for these helper functions?

5 changes: 2 additions & 3 deletions packages/xrpl/src/utils/getBalanceChanges.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import BigNumber from 'bignumber.js'
import flatten from 'lodash/flatten'
import groupBy from 'lodash/groupBy'

import {
Amount,
Expand All @@ -10,6 +8,7 @@ import {
Node,
} from '../models'

import { groupBy } from './collections'
import { dropsToXrp } from './xrpConversion'

interface BalanceChange {
Expand Down Expand Up @@ -182,5 +181,5 @@ export default function getBalanceChanges(
}
return []
})
return groupByAccount(flatten(quantities))
return groupByAccount(quantities.flat())
}
31 changes: 17 additions & 14 deletions packages/xrpl/src/utils/getNFTokenID.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import flatMap from 'lodash/flatMap'
import { decode } from 'ripple-binary-codec'

import { NFToken } from '../models/ledger/NFTokenPage'
Expand Down Expand Up @@ -72,22 +71,26 @@ 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 */

Expand Down
2 changes: 2 additions & 0 deletions packages/xrpl/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"compilerOptions": {
"pretty": true,
"target": "es6",
"lib": ["es2019", "dom"],

"outDir": "./dist/npm",
"declaration": true,
"declarationMap": true,
Expand Down
9 changes: 9 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
"compilerOptions": {
"composite": true,
"module": "commonjs",
"lib": [ "es5",
"es2015",
"es2016",
"es2017",
"es2018",
"es2019",
"es2020",
"es2021",
"esnext"],
"moduleResolution": "node",
"esModuleInterop": true,
"sourceMap": true,
Expand Down