perf: switch from lodash to rambda
authorJérôme Benoit <jerome.benoit@sap.com>
Tue, 13 Feb 2024 22:24:21 +0000 (23:24 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Tue, 13 Feb 2024 22:24:21 +0000 (23:24 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
.vscode/settings.json
bundle.js
package.json
pnpm-lock.yaml
src/charging-station/ChargingStation.ts
src/utils/Configuration.ts
src/utils/Utils.ts
tests/utils/Utils.test.ts

index af16af81e53f2593f1ca0a14fb3a27da14890fae..1138aad3366d654b762c35af2dffe557ff2e08b0 100644 (file)
@@ -43,6 +43,7 @@
     "piment",
     "poolifier",
     "preinstall",
+    "rambda",
     "Recurrency",
     "RFID",
     "shutdowning",
index 698f52a893e1204a3e5fcca499fe8ebd74210213..912d16d95ae41f32ae40a562206c4950bb43d697 100644 (file)
--- a/bundle.js
+++ b/bundle.js
@@ -23,12 +23,12 @@ await build({
     'chalk',
     'date-fns',
     'http-status-codes',
-    'lodash-es',
     'logform',
     'mnemonist',
     'mongodb',
     'node:*',
     'poolifier',
+    'rambda',
     'tar',
     'winston',
     'winston/*',
index 78c0324f1bc52d33d9bfa2a3d83a665fc1691c31..06e68b49a4d3554e69c1f65850ebb483ff50c9ff 100644 (file)
     "chalk": "^5.3.0",
     "date-fns": "^3.3.1",
     "http-status-codes": "^2.3.0",
-    "lodash-es": "^4.17.21",
     "logform": "^2.6.0",
     "mnemonist": "0.40.0-rc1",
     "mongodb": "^6.3.0",
     "poolifier": "^3.1.20",
+    "rambda": "^9.1.0",
     "tar": "^6.2.0",
     "winston": "^3.11.0",
     "winston-daily-rotate-file": "^5.0.0",
     "@commitlint/config-conventional": "^18.6.0",
     "@mikro-orm/cli": "^6.1.3",
     "@release-it/bumper": "^6.0.1",
-    "@types/lodash-es": "^4.17.12",
     "@types/node": "^20.11.17",
     "@types/tar": "^6.1.11",
     "@types/ws": "^8.5.10",
index 6a44402fd08a0d882074dbb57a58a57bdc26bbd1..3ef7bf3c6a19fc3fb092f358c13f4899f6a5a32b 100644 (file)
@@ -44,9 +44,6 @@ dependencies:
   http-status-codes:
     specifier: ^2.3.0
     version: 2.3.0
-  lodash-es:
-    specifier: ^4.17.21
-    version: 4.17.21
   logform:
     specifier: ^2.6.0
     version: 2.6.0
@@ -59,6 +56,9 @@ dependencies:
   poolifier:
     specifier: ^3.1.20
     version: 3.1.20
+  rambda:
+    specifier: ^9.1.0
+    version: 9.1.0
   tar:
     specifier: ^6.2.0
     version: 6.2.0
@@ -93,9 +93,6 @@ devDependencies:
   '@release-it/bumper':
     specifier: ^6.0.1
     version: 6.0.1(release-it@17.0.3)
-  '@types/lodash-es':
-    specifier: ^4.17.12
-    version: 4.17.12
   '@types/node':
     specifier: ^20.11.17
     version: 20.11.17
@@ -1594,16 +1591,6 @@ packages:
     resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
     dev: true
 
-  /@types/lodash-es@4.17.12:
-    resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==}
-    dependencies:
-      '@types/lodash': 4.14.202
-    dev: true
-
-  /@types/lodash@4.14.202:
-    resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==}
-    dev: true
-
   /@types/long@4.0.2:
     resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==}
     dev: true
@@ -6380,6 +6367,7 @@ packages:
 
   /lodash-es@4.17.21:
     resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
+    dev: true
 
   /lodash.camelcase@4.3.0:
     resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
@@ -8060,6 +8048,10 @@ packages:
       through2: 2.0.5
     dev: true
 
+  /rambda@9.1.0:
+    resolution: {integrity: sha512-fCRAq8Of+bAuqjAA0MSb/umbNgiYwy9N5camM2T++Qu/mRImLT3a31hf0REvnqaWCrgrdC3ewf/ucAILsYeBgQ==}
+    dev: false
+
   /randombytes@2.1.0:
     resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
     dependencies:
index a3b0328d4470a00c4eb8acf5f84d9f917a7e0410..11098648497d57e0981ab1dcac31e64a0d2ca09e 100644 (file)
@@ -8,7 +8,7 @@ import { URL } from 'node:url'
 import { parentPort } from 'node:worker_threads'
 
 import { millisecondsToSeconds, secondsToMilliseconds } from 'date-fns'
-import { merge } from 'lodash-es'
+import { mergeDeepRight } from 'rambda'
 import { type RawData, WebSocket } from 'ws'
 
 import { AutomaticTransactionGenerator } from './AutomaticTransactionGenerator.js'
@@ -1198,7 +1198,7 @@ export class ChargingStation extends EventEmitter {
         } does not match firmware version pattern '${stationInfo.firmwareVersionPattern}'`
       )
     }
-    stationInfo.firmwareUpgrade = merge(
+    stationInfo.firmwareUpgrade = mergeDeepRight(
       {
         versionUpgrade: {
           step: 1
@@ -1730,7 +1730,7 @@ export class ChargingStation extends EventEmitter {
         } else {
           delete configurationData.configurationKey
         }
-        configurationData = merge(
+        configurationData = mergeDeepRight(
           configurationData,
           buildChargingStationAutomaticTransactionGeneratorConfiguration(this)
         )
index de3a79bb1b47e943a8b061980e80783f1652164b..30ae873e672a595e362b3c9f68d8818c5b291ee7 100644 (file)
@@ -4,7 +4,7 @@ import { env } from 'node:process'
 import { fileURLToPath } from 'node:url'
 
 import chalk from 'chalk'
-import { merge } from 'lodash-es'
+import { mergeDeepRight } from 'rambda'
 
 import {
   buildPerformanceUriFilePath,
@@ -161,7 +161,7 @@ export class Configuration {
       }
     }
     if (hasOwnProp(Configuration.getConfigurationData(), ConfigurationSection.uiServer)) {
-      uiServerConfiguration = merge(
+      uiServerConfiguration = mergeDeepRight(
         uiServerConfiguration,
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         Configuration.getConfigurationData()!.uiServer!
index cff63715719b07d254b045c133a9be2170e01291..c0ee87f02234a8412019c40182a5ea3321c96b94 100644 (file)
@@ -12,6 +12,7 @@ import {
   minutesToSeconds,
   secondsToMilliseconds
 } from 'date-fns'
+import { clone as cloneDeep } from 'rambda'
 
 import { Constants } from './Constants.js'
 import {
@@ -211,55 +212,8 @@ export const extractTimeSeriesValues = (timeSeries: TimestampedData[]): number[]
   return timeSeries.map(timeSeriesItem => timeSeriesItem.value)
 }
 
-type CloneableData =
-  | number
-  | string
-  | boolean
-  | null
-  | undefined
-  | Date
-  | CloneableData[]
-  | { [key: string]: CloneableData }
-
-type FormatKey = (key: string) => string
-
-const deepClone = <I extends CloneableData, O extends CloneableData = I>(
-  value: I,
-  formatKey?: FormatKey,
-  refs: Map<I, O> = new Map<I, O>()
-): O => {
-  const ref = refs.get(value)
-  if (ref !== undefined) {
-    return ref
-  }
-  if (Array.isArray(value)) {
-    const clone: CloneableData[] = []
-    refs.set(value, clone as O)
-    for (let i = 0; i < value.length; i++) {
-      clone[i] = deepClone(value[i], formatKey, refs)
-    }
-    return clone as O
-  }
-  if (value instanceof Date) {
-    return new Date(value.getTime()) as O
-  }
-  if (typeof value !== 'object' || value === null) {
-    return value as unknown as O
-  }
-  const clone: Record<string, CloneableData> = {}
-  refs.set(value, clone as O)
-  for (const key of Object.keys(value)) {
-    clone[typeof formatKey === 'function' ? formatKey(key) : key] = deepClone(
-      value[key],
-      formatKey,
-      refs
-    )
-  }
-  return clone as O
-}
-
 export const clone = <T>(object: T): T => {
-  return deepClone(object as CloneableData) as T
+  return cloneDeep(object)
 }
 
 /**
index 6db4e36472b7d0905f731b41ff32061fce2e136c..7bee08ac625850cb73f40819d8467f3c176e8b6e 100644 (file)
@@ -345,9 +345,6 @@ await describe('Utils test suite', async () => {
     expect(clone(map)).toStrictEqual({})
     const set = new Set(['1'])
     expect(clone(set)).toStrictEqual({})
-    // The URL object seems to have not enumerable properties
-    const url = new URL('https://domain.tld')
-    expect(clone(url)).toStrictEqual({})
     const weakMap = new WeakMap([[{ 1: 1 }, { 2: 2 }]])
     expect(clone(weakMap)).toStrictEqual({})
     const weakSet = new WeakSet([{ 1: 1 }, { 2: 2 }])