diff --git a/apps/backend/package.json b/apps/backend/package.json index 707d8cc6..2723069f 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -31,7 +31,6 @@ "gurmukhi-utils": "^3.2.1", "helmet": "^7.1.0", "import-fresh": "^3.3.0", - "lodash-es": "^4.17.21", "memoizee": "^0.4.15", "node-fetch": "^3.3.2", "open": "^8.4.0", @@ -44,7 +43,6 @@ "@types/compression": "^1.7.2", "@types/cors": "^2.8.12", "@types/express": "^4.17.13", - "@types/lodash-es": "^4.17.12", "@types/node": "^20.12.12", "@types/pacote": "^11.1.8", "@types/primus": "^7.3.6", diff --git a/apps/backend/src/features/content/index.spec.ts b/apps/backend/src/features/content/index.spec.ts index 5a93e7af..1e4b3153 100644 --- a/apps/backend/src/features/content/index.spec.ts +++ b/apps/backend/src/features/content/index.spec.ts @@ -1,8 +1,8 @@ import http from 'node:http' import { Language, RecommendedSources, Writer } from '@presenter/contract' -import { first, last } from '@presenter/swiss-knife' import express from 'express' +import { first, last } from 'radashi' import { describe, expect, it } from 'vitest' import { fetchApi } from '~/../test/utils/fetch' diff --git a/apps/backend/src/features/content/state.ts b/apps/backend/src/features/content/state.ts index 154efc74..334e4041 100644 --- a/apps/backend/src/features/content/state.ts +++ b/apps/backend/src/features/content/state.ts @@ -1,6 +1,6 @@ import { Content, Line, ServerEventParameters } from '@presenter/contract' import { getLogger, mutableValue, readOnly, subscribable } from '@presenter/node' -import { first, last } from '@presenter/swiss-knife' +import { first, last } from 'radashi' import { getBaniLines, getShabad, getShabadByOrderId } from '~/services/database' diff --git a/apps/backend/src/features/history/state.ts b/apps/backend/src/features/history/state.ts index 76784b9f..0f7c51ca 100644 --- a/apps/backend/src/features/history/state.ts +++ b/apps/backend/src/features/history/state.ts @@ -2,7 +2,7 @@ import { Line, ViewedLines } from '@presenter/contract' import { HISTORY_FILE, mutableValue, readOnly, subscribable } from '@presenter/node' import * as CSV from 'csv-string' import { createWriteStream, WriteStream } from 'fs' -import { omit } from 'lodash-es' +import { omit } from 'radashi' // Fields to store in the history CSV file const CSV_FIELDS = [ diff --git a/apps/backend/src/features/settings/state.ts b/apps/backend/src/features/settings/state.ts index 9d11c229..cb8a38d6 100644 --- a/apps/backend/src/features/settings/state.ts +++ b/apps/backend/src/features/settings/state.ts @@ -1,6 +1,6 @@ import { ManyClientSettings, Settings } from '@presenter/contract' import { mutableValue, readOnly, subscribable } from '@presenter/node' -import { omit, omitBy } from 'lodash-es' +import { omit, pick } from 'radashi' import { GlobalSettings } from '~/services/global-settings' @@ -12,9 +12,9 @@ const createSettingsState = ( { globalSettings }: SettingsStateOptions ) => { const manyClientSettings = subscribable( mutableValue( {} ) ) const publicSettings = subscribable( mutableValue( {} ) ) - const omitPrivateClients = ( allSettings: ManyClientSettings ) => omitBy( + const omitPrivateClients = ( allSettings: ManyClientSettings ) => pick( allSettings, - ( _, id ) => manyClientSettings.get()[ id ]?.security.private + ( _, id ) => !manyClientSettings.get()[ id ]?.security.private ) const setSettings = ( id: string, { local, global, clients }: Partial ) => { @@ -31,7 +31,7 @@ const createSettingsState = ( { globalSettings }: SettingsStateOptions ) => { } const getClientSettings = ( id: string ): Settings => { - const clients = omit( publicSettings.get(), id ) + const clients = omit( publicSettings.get(), [ id ] ) const local = manyClientSettings.get()[ id ] const global = globalSettings.get() diff --git a/apps/backend/src/features/zoom/index.ts b/apps/backend/src/features/zoom/index.ts index 0f0546eb..5899a543 100644 --- a/apps/backend/src/features/zoom/index.ts +++ b/apps/backend/src/features/zoom/index.ts @@ -4,12 +4,12 @@ import { mutableCounter, mutableValue } from '@presenter/node' import { LANGUAGES, TRANSLATION_ORDER, TRANSLITERATION_ORDER } from '@shabados/frontend/src/lib/data' import { customiseLine, getTranslations, getTransliterators } from '@shabados/frontend/src/lib/line' import { stripVishraams, toUnicode } from 'gurmukhi-utils' -import { mapValues } from 'lodash-es' +import { mapValues } from 'radashi' import Url from 'url-parse' +import settings from '~/features/settings' import fetch from '~/helpers/fetch' import { getSources, GetSourcesResult } from '~/services/database' -import settings from '~/features/settings' const prepareSecondary = ( data, sorter ) => Object .entries( data ) diff --git a/apps/backend/src/services/database.ts b/apps/backend/src/services/database.ts index ae37e53a..20914d00 100644 --- a/apps/backend/src/services/database.ts +++ b/apps/backend/src/services/database.ts @@ -1,7 +1,7 @@ import { Bani, Language, Shabad, Source, TranslationSource } from '@presenter/contract' import { Banis, CommonBuilder, Languages, Lines, LinesBuilder, Model, Shabads, Sources, UnwrapModel, Writers } from '@shabados/database' import gurmukhiUtils from 'gurmukhi-utils' -import { groupBy, last } from 'lodash-es' +import { group, last } from 'radashi' import type { AsyncReturnType } from 'type-fest' import { MAX_RESULTS } from '~/helpers/consts' @@ -71,7 +71,7 @@ const groupTranslationSources = ( ...acc, [ id ]: { ...source, - translationSources: groupBy( translationSources, ( { languageId } ) => languageId ), + translationSources: group( translationSources, ( { languageId } ) => languageId ), }, } ) diff --git a/apps/electron/src/window.ts b/apps/electron/src/window.ts index 674d6531..048b8e4a 100644 --- a/apps/electron/src/window.ts +++ b/apps/electron/src/window.ts @@ -1,7 +1,7 @@ import * as remote from '@electron/remote/main' // eslint-disable-next-line import/no-extraneous-dependencies import { app, BrowserWindow, Menu, screen } from 'electron' -import { omit } from 'lodash' +import { omit } from 'radashi' import { isDev, PORT } from '../../../app/helpers/consts' diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 712e0b58..0deea28b 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -41,7 +41,6 @@ "gurmukhi-utils": "^3.2.2", "is-mobile": "^3.1.1", "jotai": "^2.10.1", - "lodash": "^4.17.21", "memoizee": "^0.4.17", "notistack": "^3.0.1", "partysocket": "^1.0.2", @@ -60,7 +59,6 @@ "@testing-library/jest-dom": "^6.4.5", "@testing-library/react": "^15.0.7", "@testing-library/user-event": "^14.5.2", - "@types/lodash": "^4.17.7", "@types/memoizee": "^0.4.11", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", diff --git a/apps/frontend/src/app/overlay/index.lazy.tsx b/apps/frontend/src/app/overlay/index.lazy.tsx index 47ffbd33..86e16750 100644 --- a/apps/frontend/src/app/overlay/index.lazy.tsx +++ b/apps/frontend/src/app/overlay/index.lazy.tsx @@ -1,6 +1,6 @@ import { createLazyFileRoute } from '@tanstack/react-router' import classNames from 'classnames' -import { mapValues } from 'lodash' +import { mapValues } from 'radashi' import { useContext } from 'react' import { SettingsContext } from '~/helpers/contexts' diff --git a/apps/frontend/src/app/presenter/-components/Display/index.tsx b/apps/frontend/src/app/presenter/-components/Display/index.tsx index e5df2307..0b26a395 100644 --- a/apps/frontend/src/app/presenter/-components/Display/index.tsx +++ b/apps/frontend/src/app/presenter/-components/Display/index.tsx @@ -1,7 +1,7 @@ import './index.css' import classNames from 'classnames' -import { mapValues } from 'lodash' +import { mapValues } from 'radashi' import { LANGUAGES } from '~/helpers/data' import { customiseLine, getTransliterators } from '~/helpers/line' diff --git a/apps/frontend/src/app/presenter/controller/navigator/index.tsx b/apps/frontend/src/app/presenter/controller/navigator/index.tsx index 7cfbbffb..4c00a4c5 100644 --- a/apps/frontend/src/app/presenter/controller/navigator/index.tsx +++ b/apps/frontend/src/app/presenter/controller/navigator/index.tsx @@ -16,7 +16,7 @@ import ListItem from '@mui/material/ListItem' import { createFileRoute } from '@tanstack/react-router' import classNames from 'classnames' import { stripVishraams } from 'gurmukhi-utils' -import { invert } from 'lodash' +import { invert } from 'radashi' import { useCallback, useContext, useEffect, useMemo, useState } from 'react' import GlobalHotKeys from '~/components/GlobalHotKeys' diff --git a/apps/frontend/src/app/settings/client/hotkeys/index.tsx b/apps/frontend/src/app/settings/client/hotkeys/index.tsx index 6f599b4d..83f905fb 100644 --- a/apps/frontend/src/app/settings/client/hotkeys/index.tsx +++ b/apps/frontend/src/app/settings/client/hotkeys/index.tsx @@ -5,7 +5,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { Button, Grid, List, ListItem, Tooltip, Typography } from '@mui/material' import { createFileRoute } from '@tanstack/react-router' import classNames from 'classnames' -import { groupBy } from 'lodash' +import { group } from 'radashi' import { useState } from 'react' import keyMap from '~/helpers/keyMap' @@ -93,7 +93,7 @@ const Hotkeys = ( { keys, shortcuts, device }: HotkeysProps ) => { {Object - .entries( groupBy( shortcuts, ( { group } ) => group ) ) + .entries( group( shortcuts, ( { group } ) => group ) ) .map( ( [ groupName, hotkeys ] ) => ( diff --git a/apps/frontend/src/components/CopyHotkeys.tsx b/apps/frontend/src/components/CopyHotkeys.tsx index b038dae5..f71717ab 100644 --- a/apps/frontend/src/components/CopyHotkeys.tsx +++ b/apps/frontend/src/components/CopyHotkeys.tsx @@ -1,5 +1,5 @@ import { stripVishraams, toUnicode } from 'gurmukhi-utils' -import { mapValues } from 'lodash' +import { mapValues } from 'radashi' import { ReactNode, useContext } from 'react' import { RecommendedSourcesContext, SettingsContext, WritersContext } from '~/helpers/contexts' diff --git a/apps/frontend/src/components/GlobalHotKeys.tsx b/apps/frontend/src/components/GlobalHotKeys.tsx index c1977a6c..7a8d366d 100644 --- a/apps/frontend/src/components/GlobalHotKeys.tsx +++ b/apps/frontend/src/components/GlobalHotKeys.tsx @@ -1,4 +1,4 @@ -import { mapValues } from 'lodash' +import { mapValues } from 'radashi' import { ReactNode } from 'react' import { configure, GlobalHotKeys as HotKeys } from 'react-hotkeys/es' import KeyEventManager from 'react-hotkeys/es/lib/KeyEventManager' diff --git a/apps/frontend/src/components/NavigatorHotkeys.tsx b/apps/frontend/src/components/NavigatorHotkeys.tsx index 4d8ebdd4..5c91c195 100644 --- a/apps/frontend/src/components/NavigatorHotkeys.tsx +++ b/apps/frontend/src/components/NavigatorHotkeys.tsx @@ -1,4 +1,4 @@ -import { noop } from 'lodash' +import { noop } from 'radashi' import { useCallback, useContext, useEffect } from 'react' import { getJumpLines } from '~/helpers/auto-jump' diff --git a/apps/frontend/src/helpers/auto-jump.ts b/apps/frontend/src/helpers/auto-jump.ts index 64c1d0b2..fae8b17a 100644 --- a/apps/frontend/src/helpers/auto-jump.ts +++ b/apps/frontend/src/helpers/auto-jump.ts @@ -1,6 +1,6 @@ import { ClientEventParameters } from '@presenter/contract' -import { find, findIndex, findLastIndex, invert } from 'lodash' import memoize from 'memoizee' +import { invert } from 'radashi' import { BANIS } from './data' @@ -64,17 +64,16 @@ export const getBaniNextJumpLine = ( { content, lineId } ) => { const currentLine = lines[ currentLineIndex ] // Get next jump line by searching for it from the current line's index - const nextJumpLineFinder = () => find( - lines, + const nextJumpLineFinder = () => lines.find( ( { id } ) => !!jumpLines[ id ], Math.min( currentLineIndex + 1, lines.length - 1 ), ) || {} // Returns a line from the current line's index, based on a regex const regexFinder = ( regex: RegExp, forward = true, offset = currentLineIndex ) => { - const findFn = forward ? findIndex : findLastIndex + const findFn = forward ? lines.indexOf : lines.lastIndexOf - return findFn( lines, ( { gurmukhi } ) => regex.test( gurmukhi ), offset ) + return findFn( ( { gurmukhi } ) => regex.test( gurmukhi ), offset ) } // Gets the next line after the last pauri diff --git a/apps/frontend/src/helpers/data.ts b/apps/frontend/src/helpers/data.ts index 6a67fc0b..f6801ef5 100644 --- a/apps/frontend/src/helpers/data.ts +++ b/apps/frontend/src/helpers/data.ts @@ -2,7 +2,7 @@ *! Shared with backend. To be refactored into shared location. */ import { toEnglish, toHindi, toShahmukhi, toUnicode } from 'gurmukhi-utils' -import { invert } from 'lodash' +import { invert } from 'radashi' // Bani IDs export const BANIS = { @@ -21,9 +21,7 @@ export const LANGUAGES = { // Languages by keyed by IDs export const LANGUAGE_NAMES = invert( LANGUAGES ) -export type Transliterators = { - [language: string]: ( ascii: string ) => string, -} +export type Transliterators = Record string> // The transliterator functions for each language, presuming ascii input export const TRANSLITERATORS = Object.entries( { @@ -35,9 +33,7 @@ export const TRANSLITERATORS = Object.entries( { [ language ]: ( ascii: string ) => fn( toUnicode( ascii ) ), } ), {} as Transliterators ) -export type Translations = { - [language: string]: number, -} +export type Translations = Record // The order of translations export const TRANSLATION_ORDER = [ diff --git a/apps/frontend/src/helpers/utils.ts b/apps/frontend/src/helpers/utils.ts index c9bf7020..4776cc5c 100644 --- a/apps/frontend/src/helpers/utils.ts +++ b/apps/frontend/src/helpers/utils.ts @@ -1,5 +1,5 @@ import deepmerge from 'deepmerge' -import { debounce } from 'lodash' +import { debounce } from 'radashi' import { findDOMNode } from 'react-dom' import scrollIntoView from 'scroll-into-view' @@ -17,7 +17,7 @@ export const scrollIntoCenter = ( ref: any, options?: __ScrollIntoView.Settings { time: 200, ...options } ) -export const debounceHotKey = ( fn: () => void ) => debounce( fn, 300, { leading: true } ) +export const debounceHotKey = ( fn: () => void ) => debounce( { leading: true, delay: 300 }, fn ) export const mapPlatformKey = ( key: string ) => ( isMac ? key.replace( 'ctrl', 'cmd' ) : key ) diff --git a/package-lock.json b/package-lock.json index 420e0587..4d6c7b8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,13 +15,12 @@ "dependencies": { "@presenter/contract": "*", "deepmerge": "^4.3.1", - "lodash-es": "^4.17.21", - "make-error": "^1.3.6" + "make-error": "^1.3.6", + "radashi": "^12.2.0" }, "devDependencies": { "@presenter/tsconfig": "*", "@shabados/eslint-config": "^0.14.0", - "@types/lodash-es": "^4.17.12", "type-fest": "^4.18.2", "typescript": "^5.5.4", "undici": "^6.18.0", @@ -55,7 +54,6 @@ "gurmukhi-utils": "^3.2.1", "helmet": "^7.1.0", "import-fresh": "^3.3.0", - "lodash-es": "^4.17.21", "memoizee": "^0.4.15", "node-fetch": "^3.3.2", "open": "^8.4.0", @@ -68,7 +66,6 @@ "@types/compression": "^1.7.2", "@types/cors": "^2.8.12", "@types/express": "^4.17.13", - "@types/lodash-es": "^4.17.12", "@types/node": "^20.12.12", "@types/pacote": "^11.1.8", "@types/primus": "^7.3.6", @@ -395,7 +392,6 @@ "gurmukhi-utils": "^3.2.2", "is-mobile": "^3.1.1", "jotai": "^2.10.1", - "lodash": "^4.17.21", "memoizee": "^0.4.17", "notistack": "^3.0.1", "partysocket": "^1.0.2", @@ -414,7 +410,6 @@ "@testing-library/jest-dom": "^6.4.5", "@testing-library/react": "^15.0.7", "@testing-library/user-event": "^14.5.2", - "@types/lodash": "^4.17.7", "@types/memoizee": "^0.4.11", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", @@ -3175,19 +3170,6 @@ "@types/node": "*" } }, - "node_modules/@types/lodash": { - "version": "4.17.7", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/lodash-es": { - "version": "4.17.12", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/lodash": "*" - } - }, "node_modules/@types/memoizee": { "version": "0.4.11", "dev": true, @@ -10481,10 +10463,6 @@ "version": "4.17.21", "license": "MIT" }, - "node_modules/lodash-es": { - "version": "4.17.21", - "license": "MIT" - }, "node_modules/lodash.escaperegexp": { "version": "4.1.2", "license": "MIT" @@ -12767,6 +12745,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/radashi": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/radashi/-/radashi-12.2.0.tgz", + "integrity": "sha512-LeYD1SabvzUss1csIqSx5nVjUn2tg8zZykSiadmAfF0fEdAL18sMdn9oFkzniy5WEdqSq249MnnIqK5eVzluVw==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/range-parser": { "version": "1.2.1", "license": "MIT", diff --git a/package.json b/package.json index 3729b30b..c9e2e6f4 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,6 @@ "devDependencies": { "@presenter/tsconfig": "*", "@shabados/eslint-config": "^0.14.0", - "@types/lodash-es": "^4.17.12", "type-fest": "^4.18.2", "typescript": "^5.5.4", "undici": "^6.18.0", @@ -26,7 +25,7 @@ "dependencies": { "@presenter/contract": "*", "deepmerge": "^4.3.1", - "lodash-es": "^4.17.21", - "make-error": "^1.3.6" + "make-error": "^1.3.6", + "radashi": "^12.2.0" } } diff --git a/packages/node/src/mutable-value.ts b/packages/node/src/mutable-value.ts index 0a61a0f7..22e49922 100644 --- a/packages/node/src/mutable-value.ts +++ b/packages/node/src/mutable-value.ts @@ -1,5 +1,5 @@ import { EventEmitter } from 'eventemitter3' -import { debounce } from 'lodash-es' +import { debounce } from 'radashi' export type ReadOnlyMutable = { get: () => T } export type WriteOnlyMutable = { set: ( value: T ) => void } @@ -33,7 +33,7 @@ export const subscribable = ( { get, set }: Mutable ) => { const onChange = ( fn: ( value: T ) => void ) => emitter.on( 'change', fn ) - const emit = debounce( () => emitter.emit( 'change', get() ) ) + const emit = debounce( { delay: 0 }, () => emitter.emit( 'change', get() ) ) const setWithEmit = ( value: T ) => { set( value ) diff --git a/packages/swiss-knife/src/array.ts b/packages/swiss-knife/src/array.ts deleted file mode 100644 index 0bc41447..00000000 --- a/packages/swiss-knife/src/array.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const first = ( array: T[] ) => array[ 0 ] - -export const last = ( array: T[] ) => array[ array.length - 1 ] diff --git a/packages/swiss-knife/src/index.ts b/packages/swiss-knife/src/index.ts index 85bb626f..d0415704 100644 --- a/packages/swiss-knife/src/index.ts +++ b/packages/swiss-knife/src/index.ts @@ -1,2 +1 @@ -export * from './array' export * from './json'