diff --git a/.eslintrc.js b/.eslintrc.js index e2d16a54a83..1b36bcee253 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -245,7 +245,7 @@ module.exports = defineConfig({ }, // Immutable / Redux / data store { - pattern: '{immutable,react-redux,react-immutable-proptypes,react-immutable-pure-component,reselect}', + pattern: '{immutable,@reduxjs/toolkit,react-redux,react-immutable-proptypes,react-immutable-pure-component}', group: 'external', position: 'before', }, @@ -353,7 +353,14 @@ module.exports = defineConfig({ '@typescript-eslint/consistent-type-exports': 'error', '@typescript-eslint/consistent-type-imports': 'error', "@typescript-eslint/prefer-nullish-coalescing": ['error', { ignorePrimitives: { boolean: true } }], - + "@typescript-eslint/no-restricted-imports": [ + "warn", + { + "name": "react-redux", + "importNames": ["useSelector", "useDispatch"], + "message": "Use typed hooks `useAppDispatch` and `useAppSelector` instead." + } + ], 'jsdoc/require-jsdoc': 'off', // Those rules set stricter rules for TS files diff --git a/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js b/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js index a0e50029dfa..8cf906b20a4 100644 --- a/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js +++ b/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js @@ -1,6 +1,7 @@ +import { createSelector } from '@reduxjs/toolkit'; import { Map as ImmutableMap } from 'immutable'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; + import { useEmoji } from '../../../actions/emojis'; import { changeSetting } from '../../../actions/settings'; diff --git a/app/javascript/mastodon/features/compose/containers/language_dropdown_container.js b/app/javascript/mastodon/features/compose/containers/language_dropdown_container.js index e1e2f040241..ba4b5f05a59 100644 --- a/app/javascript/mastodon/features/compose/containers/language_dropdown_container.js +++ b/app/javascript/mastodon/features/compose/containers/language_dropdown_container.js @@ -1,6 +1,7 @@ +import { createSelector } from '@reduxjs/toolkit'; import { Map as ImmutableMap } from 'immutable'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; + import { changeComposeLanguage } from 'mastodon/actions/compose'; import { useLanguage } from 'mastodon/actions/languages'; diff --git a/app/javascript/mastodon/features/getting_started/containers/announcements_container.js b/app/javascript/mastodon/features/getting_started/containers/announcements_container.js index c33e624324d..3bb1b8e8d18 100644 --- a/app/javascript/mastodon/features/getting_started/containers/announcements_container.js +++ b/app/javascript/mastodon/features/getting_started/containers/announcements_container.js @@ -1,6 +1,7 @@ +import { createSelector } from '@reduxjs/toolkit'; import { Map as ImmutableMap } from 'immutable'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; + import { addReaction, removeReaction, dismissAnnouncement } from 'mastodon/actions/announcements'; diff --git a/app/javascript/mastodon/features/home_timeline/index.jsx b/app/javascript/mastodon/features/home_timeline/index.jsx index 7c9c7a4e52e..613eb4b8966 100644 --- a/app/javascript/mastodon/features/home_timeline/index.jsx +++ b/app/javascript/mastodon/features/home_timeline/index.jsx @@ -6,9 +6,9 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; import { Helmet } from 'react-helmet'; +import { createSelector } from '@reduxjs/toolkit'; import { List as ImmutableList } from 'immutable'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as CampaignIcon } from '@material-symbols/svg-600/outlined/campaign.svg'; import { ReactComponent as HomeIcon } from '@material-symbols/svg-600/outlined/home-fill.svg'; diff --git a/app/javascript/mastodon/features/list_adder/index.jsx b/app/javascript/mastodon/features/list_adder/index.jsx index 1ba9972e00d..4e7bd46bdfd 100644 --- a/app/javascript/mastodon/features/list_adder/index.jsx +++ b/app/javascript/mastodon/features/list_adder/index.jsx @@ -2,10 +2,10 @@ import PropTypes from 'prop-types'; import { injectIntl } from 'react-intl'; +import { createSelector } from '@reduxjs/toolkit'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { setupListAdder, resetListAdder } from '../../actions/lists'; import NewListForm from '../lists/components/new_list_form'; diff --git a/app/javascript/mastodon/features/lists/index.jsx b/app/javascript/mastodon/features/lists/index.jsx index 58e85b4d288..9014394351a 100644 --- a/app/javascript/mastodon/features/lists/index.jsx +++ b/app/javascript/mastodon/features/lists/index.jsx @@ -4,10 +4,10 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { Helmet } from 'react-helmet'; +import { createSelector } from '@reduxjs/toolkit'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as ListAltIcon } from '@material-symbols/svg-600/outlined/list_alt.svg'; diff --git a/app/javascript/mastodon/features/notifications/index.jsx b/app/javascript/mastodon/features/notifications/index.jsx index 379932b7b7f..762c96cccaf 100644 --- a/app/javascript/mastodon/features/notifications/index.jsx +++ b/app/javascript/mastodon/features/notifications/index.jsx @@ -5,10 +5,10 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { Helmet } from 'react-helmet'; +import { createSelector } from '@reduxjs/toolkit'; import { List as ImmutableList } from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as DoneAllIcon } from '@material-symbols/svg-600/outlined/done_all.svg'; import { ReactComponent as NotificationsIcon } from '@material-symbols/svg-600/outlined/notifications-fill.svg'; diff --git a/app/javascript/mastodon/features/report/comment.jsx b/app/javascript/mastodon/features/report/comment.jsx index ec597469234..b80c14fcb92 100644 --- a/app/javascript/mastodon/features/report/comment.jsx +++ b/app/javascript/mastodon/features/report/comment.jsx @@ -3,10 +3,10 @@ import { useCallback, useEffect, useRef } from 'react'; import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; +import { createSelector } from '@reduxjs/toolkit'; import { OrderedSet, List as ImmutableList } from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { shallowEqual } from 'react-redux'; -import { createSelector } from 'reselect'; import Toggle from 'react-toggle'; diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index c581255c992..38324897648 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -6,11 +6,11 @@ import classNames from 'classnames'; import { Helmet } from 'react-helmet'; import { withRouter } from 'react-router-dom'; +import { createSelector } from '@reduxjs/toolkit'; import Immutable from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as VisibilityIcon } from '@material-symbols/svg-600/outlined/visibility.svg'; import { ReactComponent as VisibilityOffIcon } from '@material-symbols/svg-600/outlined/visibility_off.svg'; diff --git a/app/javascript/mastodon/features/subscribed_languages_modal/index.jsx b/app/javascript/mastodon/features/subscribed_languages_modal/index.jsx index 147e11d1be1..ac34f7986cb 100644 --- a/app/javascript/mastodon/features/subscribed_languages_modal/index.jsx +++ b/app/javascript/mastodon/features/subscribed_languages_modal/index.jsx @@ -2,11 +2,11 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; +import { createSelector } from '@reduxjs/toolkit'; import { is, List as ImmutableList, Set as ImmutableSet } from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg'; diff --git a/app/javascript/mastodon/features/ui/components/list_panel.jsx b/app/javascript/mastodon/features/ui/components/list_panel.jsx index 8dbd28f0940..ff600730a0e 100644 --- a/app/javascript/mastodon/features/ui/components/list_panel.jsx +++ b/app/javascript/mastodon/features/ui/components/list_panel.jsx @@ -1,9 +1,9 @@ import PropTypes from 'prop-types'; +import { createSelector } from '@reduxjs/toolkit'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as ListAltIcon } from '@material-symbols/svg-600/outlined/list_alt.svg'; diff --git a/app/javascript/mastodon/features/ui/containers/status_list_container.js b/app/javascript/mastodon/features/ui/containers/status_list_container.js index 36a8f58f8b5..3e7ae2add02 100644 --- a/app/javascript/mastodon/features/ui/containers/status_list_container.js +++ b/app/javascript/mastodon/features/ui/containers/status_list_container.js @@ -1,6 +1,6 @@ +import { createSelector } from '@reduxjs/toolkit'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { debounce } from 'lodash'; diff --git a/app/javascript/mastodon/reducers/accounts.ts b/app/javascript/mastodon/reducers/accounts.ts index f7270eb60a5..e6f07340c04 100644 --- a/app/javascript/mastodon/reducers/accounts.ts +++ b/app/javascript/mastodon/reducers/accounts.ts @@ -1,7 +1,6 @@ +import type { Reducer } from '@reduxjs/toolkit'; import { Map as ImmutableMap } from 'immutable'; -import type { Reducer } from 'redux'; - import { followAccountSuccess, unfollowAccountSuccess, diff --git a/app/javascript/mastodon/reducers/modal.ts b/app/javascript/mastodon/reducers/modal.ts index 73a2afb916c..368f26542c0 100644 --- a/app/javascript/mastodon/reducers/modal.ts +++ b/app/javascript/mastodon/reducers/modal.ts @@ -1,6 +1,5 @@ -import { Record as ImmutableRecord, Stack } from 'immutable'; - import type { Reducer } from '@reduxjs/toolkit'; +import { Record as ImmutableRecord, Stack } from 'immutable'; import { COMPOSE_UPLOAD_CHANGE_SUCCESS } from '../actions/compose'; import type { ModalType } from '../actions/modal'; diff --git a/app/javascript/mastodon/reducers/relationships.ts b/app/javascript/mastodon/reducers/relationships.ts index 2ba61839c7b..dcca11b2032 100644 --- a/app/javascript/mastodon/reducers/relationships.ts +++ b/app/javascript/mastodon/reducers/relationships.ts @@ -1,7 +1,6 @@ -import { Map as ImmutableMap } from 'immutable'; - import { isFulfilled } from '@reduxjs/toolkit'; -import type { Reducer } from 'redux'; +import type { Reducer } from '@reduxjs/toolkit'; +import { Map as ImmutableMap } from 'immutable'; import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships'; import type { Account } from 'mastodon/models/account'; diff --git a/app/javascript/mastodon/selectors/accounts.ts b/app/javascript/mastodon/selectors/accounts.ts index 66193136c45..cee3a87bca0 100644 --- a/app/javascript/mastodon/selectors/accounts.ts +++ b/app/javascript/mastodon/selectors/accounts.ts @@ -1,5 +1,5 @@ +import { createSelector } from '@reduxjs/toolkit'; import { Record as ImmutableRecord } from 'immutable'; -import { createSelector } from 'reselect'; import { accountDefaultValues } from 'mastodon/models/account'; import type { Account, AccountShape } from 'mastodon/models/account'; diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js index 8a07ba774d8..b1c60403e9f 100644 --- a/app/javascript/mastodon/selectors/index.js +++ b/app/javascript/mastodon/selectors/index.js @@ -1,5 +1,5 @@ +import { createSelector } from '@reduxjs/toolkit'; import { List as ImmutableList, Map as ImmutableMap } from 'immutable'; -import { createSelector } from 'reselect'; import { toServerSideType } from 'mastodon/utils/filters'; diff --git a/app/javascript/mastodon/store/middlewares/errors.ts b/app/javascript/mastodon/store/middlewares/errors.ts index 9f28f5ff53f..e11aa781782 100644 --- a/app/javascript/mastodon/store/middlewares/errors.ts +++ b/app/javascript/mastodon/store/middlewares/errors.ts @@ -1,20 +1,34 @@ -import type { AnyAction, Middleware } from 'redux'; +import { isAction } from '@reduxjs/toolkit'; +import type { Action, Middleware } from '@reduxjs/toolkit'; import type { RootState } from '..'; import { showAlertForError } from '../../actions/alerts'; const defaultFailSuffix = 'FAIL'; +const isFailedAction = new RegExp(`${defaultFailSuffix}$`, 'g'); -export const errorsMiddleware: Middleware = +interface ActionWithMaybeAlertParams extends Action { + skipAlert?: boolean; + skipNotFound?: boolean; + error?: unknown; +} + +function isActionWithmaybeAlertParams( + action: unknown, +): action is ActionWithMaybeAlertParams { + return isAction(action); +} + +export const errorsMiddleware: Middleware, RootState> = ({ dispatch }) => (next) => - (action: AnyAction & { skipAlert?: boolean; skipNotFound?: boolean }) => { - if (action.type && !action.skipAlert) { - const isFail = new RegExp(`${defaultFailSuffix}$`, 'g'); - - if (typeof action.type === 'string' && action.type.match(isFail)) { - dispatch(showAlertForError(action.error, action.skipNotFound)); - } + (action) => { + if ( + isActionWithmaybeAlertParams(action) && + !action.skipAlert && + action.type.match(isFailedAction) + ) { + dispatch(showAlertForError(action.error, action.skipNotFound)); } return next(action); diff --git a/app/javascript/mastodon/store/middlewares/loading_bar.ts b/app/javascript/mastodon/store/middlewares/loading_bar.ts index 83056ee49f4..d259be899b1 100644 --- a/app/javascript/mastodon/store/middlewares/loading_bar.ts +++ b/app/javascript/mastodon/store/middlewares/loading_bar.ts @@ -3,9 +3,11 @@ import { isPending as isThunkActionPending, isFulfilled as isThunkActionFulfilled, isRejected as isThunkActionRejected, + isAction, } from '@reduxjs/toolkit'; +import type { Middleware, UnknownAction } from '@reduxjs/toolkit'; + import { showLoading, hideLoading } from 'react-redux-loading-bar'; -import type { AnyAction, Middleware } from 'redux'; import type { RootState } from '..'; @@ -19,14 +21,28 @@ const defaultTypeSuffixes: Config['promiseTypeSuffixes'] = [ 'REJECTED', ]; +interface ActionWithSkipLoading extends UnknownAction { + skipLoading: boolean; +} + +function isActionWithSkipLoading( + action: unknown, +): action is ActionWithSkipLoading { + return ( + isAction(action) && + 'skipLoading' in action && + typeof action.skipLoading === 'boolean' + ); +} + export const loadingBarMiddleware = ( config: Config = {}, -): Middleware => { +): Middleware<{ skipLoading?: boolean }, RootState> => { const promiseTypeSuffixes = config.promiseTypeSuffixes ?? defaultTypeSuffixes; return ({ dispatch }) => (next) => - (action: AnyAction) => { + (action) => { let isPending = false; let isFulfilled = false; let isRejected = false; @@ -39,7 +55,7 @@ export const loadingBarMiddleware = ( else if (isThunkActionFulfilled(action)) isFulfilled = true; else if (isThunkActionRejected(action)) isRejected = true; } else if ( - action.type && + isActionWithSkipLoading(action) && !action.skipLoading && typeof action.type === 'string' ) { diff --git a/app/javascript/mastodon/store/middlewares/sounds.ts b/app/javascript/mastodon/store/middlewares/sounds.ts index 09ade7d7532..51839f427ae 100644 --- a/app/javascript/mastodon/store/middlewares/sounds.ts +++ b/app/javascript/mastodon/store/middlewares/sounds.ts @@ -1,4 +1,5 @@ -import type { Middleware, AnyAction } from 'redux'; +import { isAction } from '@reduxjs/toolkit'; +import type { Middleware, UnknownAction } from '@reduxjs/toolkit'; import ready from 'mastodon/ready'; import { assetHost } from 'mastodon/utils/config'; @@ -10,6 +11,21 @@ interface AudioSource { type: string; } +interface ActionWithMetaSound extends UnknownAction { + meta: { sound: string }; +} + +function isActionWithMetaSound(action: unknown): action is ActionWithMetaSound { + return ( + isAction(action) && + 'meta' in action && + typeof action.meta === 'object' && + !!action.meta && + 'sound' in action.meta && + typeof action.meta.sound === 'string' + ); +} + const createAudio = (sources: AudioSource[]) => { const audio = new Audio(); sources.forEach(({ type, src }) => { @@ -34,7 +50,10 @@ const play = (audio: HTMLAudioElement) => { void audio.play(); }; -export const soundsMiddleware = (): Middleware => { +export const soundsMiddleware = (): Middleware< + Record, + RootState +> => { const soundCache: Record = {}; void ready(() => { @@ -50,15 +69,15 @@ export const soundsMiddleware = (): Middleware => { ]); }); - return () => - (next) => - (action: AnyAction & { meta?: { sound?: string } }) => { - const sound = action.meta?.sound; + return () => (next) => (action) => { + if (isActionWithMetaSound(action)) { + const sound = action.meta.sound; if (sound && Object.hasOwn(soundCache, sound)) { play(soundCache[sound]); } + } - return next(action); - }; + return next(action); + }; }; diff --git a/app/javascript/mastodon/store/typed_functions.ts b/app/javascript/mastodon/store/typed_functions.ts index f1e71385a88..46a10b8b478 100644 --- a/app/javascript/mastodon/store/typed_functions.ts +++ b/app/javascript/mastodon/store/typed_functions.ts @@ -1,7 +1,7 @@ -import type { TypedUseSelectorHook } from 'react-redux'; -import { useDispatch, useSelector } from 'react-redux'; - import { createAsyncThunk } from '@reduxjs/toolkit'; +import type { TypedUseSelectorHook } from 'react-redux'; +// eslint-disable-next-line @typescript-eslint/no-restricted-imports +import { useDispatch, useSelector } from 'react-redux'; import type { AppDispatch, RootState } from './store'; diff --git a/config/webpack/rules/babel.js b/config/webpack/rules/babel.js index 2811a1674d8..c7bf886e795 100644 --- a/config/webpack/rules/babel.js +++ b/config/webpack/rules/babel.js @@ -7,8 +7,14 @@ module.exports = { include: [ settings.source_path, ...settings.resolved_paths, + 'node_modules/@reduxjs' ].map(p => resolve(p)), - exclude: /node_modules/, + exclude: function(modulePath) { + return ( + /node_modules/.test(modulePath) && + !/@reduxjs/.test(modulePath) + ); + }, use: [ { loader: 'babel-loader', diff --git a/package.json b/package.json index a5b6a228ca4..16ed4decaa2 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@github/webauthn-json": "^2.1.1", "@material-symbols/svg-600": "^0.14.0", "@rails/ujs": "^7.1.1", - "@reduxjs/toolkit": "^1.9.5", + "@reduxjs/toolkit": "^2.0.1", "@svgr/webpack": "^5.5.0", "arrow-key-navigation": "^1.2.0", "async-mutex": "^0.4.0", @@ -106,8 +106,8 @@ "react-motion": "^0.5.2", "react-notification": "^6.8.5", "react-overlays": "^5.2.1", - "react-redux": "^8.0.4", - "react-redux-loading-bar": "^5.0.4", + "react-redux": "^9.0.4", + "react-redux-loading-bar": "^5.0.8", "react-router": "^5.3.4", "react-router-dom": "^5.3.4", "react-router-scroll-4": "^1.0.0-beta.1", @@ -116,12 +116,9 @@ "react-swipeable-views": "^0.14.0", "react-textarea-autosize": "^8.4.1", "react-toggle": "^4.1.3", - "redux": "^4.2.1", "redux-immutable": "^4.0.0", - "redux-thunk": "^2.4.2", "regenerator-runtime": "^0.14.0", "requestidlecallback": "^0.3.0", - "reselect": "^4.1.8", "rimraf": "^5.0.1", "sass": "^1.62.1", "sass-loader": "^10.2.0", diff --git a/yarn.lock b/yarn.lock index 70d98332ad4..71ed44a4463 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1483,7 +1483,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.22.3, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.22.3, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": version: 7.23.7 resolution: "@babel/runtime@npm:7.23.7" dependencies: @@ -2302,7 +2302,7 @@ __metadata: "@github/webauthn-json": "npm:^2.1.1" "@material-symbols/svg-600": "npm:^0.14.0" "@rails/ujs": "npm:^7.1.1" - "@reduxjs/toolkit": "npm:^1.9.5" + "@reduxjs/toolkit": "npm:^2.0.1" "@svgr/webpack": "npm:^5.5.0" "@testing-library/jest-dom": "npm:^6.0.0" "@testing-library/react": "npm:^14.0.0" @@ -2410,8 +2410,8 @@ __metadata: react-motion: "npm:^0.5.2" react-notification: "npm:^6.8.5" react-overlays: "npm:^5.2.1" - react-redux: "npm:^8.0.4" - react-redux-loading-bar: "npm:^5.0.4" + react-redux: "npm:^9.0.4" + react-redux-loading-bar: "npm:^5.0.8" react-router: "npm:^5.3.4" react-router-dom: "npm:^5.3.4" react-router-scroll-4: "npm:^1.0.0-beta.1" @@ -2421,12 +2421,9 @@ __metadata: react-test-renderer: "npm:^18.2.0" react-textarea-autosize: "npm:^8.4.1" react-toggle: "npm:^4.1.3" - redux: "npm:^4.2.1" redux-immutable: "npm:^4.0.0" - redux-thunk: "npm:^2.4.2" regenerator-runtime: "npm:^0.14.0" requestidlecallback: "npm:^0.3.0" - reselect: "npm:^4.1.8" rimraf: "npm:^5.0.1" sass: "npm:^1.62.1" sass-loader: "npm:^10.2.0" @@ -2622,23 +2619,23 @@ __metadata: languageName: node linkType: hard -"@reduxjs/toolkit@npm:^1.9.5": - version: 1.9.7 - resolution: "@reduxjs/toolkit@npm:1.9.7" +"@reduxjs/toolkit@npm:^2.0.1": + version: 2.0.1 + resolution: "@reduxjs/toolkit@npm:2.0.1" dependencies: - immer: "npm:^9.0.21" - redux: "npm:^4.2.1" - redux-thunk: "npm:^2.4.2" - reselect: "npm:^4.1.8" + immer: "npm:^10.0.3" + redux: "npm:^5.0.0" + redux-thunk: "npm:^3.1.0" + reselect: "npm:^5.0.1" peerDependencies: react: ^16.9.0 || ^17.0.0 || ^18 - react-redux: ^7.2.1 || ^8.0.2 + react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0 peerDependenciesMeta: react: optional: true react-redux: optional: true - checksum: fa0aa4b7c6973ac87ce0ac7e45faa02c73b66c4ee0bc950d178494539a42a1bb908d109297102458b7ea14d5e7dae356e7a7ce9a1b9849b0e8451e6dd70fca9c + checksum: 161b9b8e11d9688890ab97b604a4c10c0d41b1369425a5fa821586932db4cd5a391d15799732b3612e6120a6336458ff577ff254219315c05ecd68da5d15fd79 languageName: node linkType: hard @@ -9128,10 +9125,10 @@ __metadata: languageName: node linkType: hard -"immer@npm:^9.0.21": - version: 9.0.21 - resolution: "immer@npm:9.0.21" - checksum: 03ea3ed5d4d72e8bd428df4a38ad7e483ea8308e9a113d3b42e0ea2cc0cc38340eb0a6aca69592abbbf047c685dbda04e3d34bf2ff438ab57339ed0a34cc0a05 +"immer@npm:^10.0.3": + version: 10.0.3 + resolution: "immer@npm:10.0.3" + checksum: 282a4f8479a40f7d12b2b3243c095e3e892bf99058e2ffcdd6b8e9fd143e6a90f2717ab9b6c8b97c927ffb8054465c8f647056f41660dbfd672e240cf1063503 languageName: node linkType: hard @@ -13104,7 +13101,17 @@ __metadata: languageName: node linkType: hard -"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.13, postcss-selector-parser@npm:^6.0.15, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4": +"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.13, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4": + version: 6.0.13 + resolution: "postcss-selector-parser@npm:6.0.13" + dependencies: + cssesc: "npm:^3.0.0" + util-deprecate: "npm:^1.0.2" + checksum: 51f099b27f7c7198ea1826470ef0adfa58b3bd3f59b390fda123baa0134880a5fa9720137b6009c4c1373357b144f700b0edac73335d0067422063129371444e + languageName: node + linkType: hard + +"postcss-selector-parser@npm:^6.0.15": version: 6.0.15 resolution: "postcss-selector-parser@npm:6.0.15" dependencies: @@ -13693,7 +13700,7 @@ __metadata: languageName: node linkType: hard -"react-redux-loading-bar@npm:^5.0.4": +"react-redux-loading-bar@npm:^5.0.8": version: 5.0.8 resolution: "react-redux-loading-bar@npm:5.0.8" dependencies: @@ -13708,35 +13715,25 @@ __metadata: languageName: node linkType: hard -"react-redux@npm:^8.0.4": - version: 8.1.3 - resolution: "react-redux@npm:8.1.3" +"react-redux@npm:^9.0.4": + version: 9.0.4 + resolution: "react-redux@npm:9.0.4" dependencies: - "@babel/runtime": "npm:^7.12.1" - "@types/hoist-non-react-statics": "npm:^3.3.1" "@types/use-sync-external-store": "npm:^0.0.3" - hoist-non-react-statics: "npm:^3.3.2" - react-is: "npm:^18.0.0" use-sync-external-store: "npm:^1.0.0" peerDependencies: - "@types/react": ^16.8 || ^17.0 || ^18.0 - "@types/react-dom": ^16.8 || ^17.0 || ^18.0 - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - react-native: ">=0.59" - redux: ^4 || ^5.0.0-beta.0 + "@types/react": ^18.2.25 + react: ^18.0 + react-native: ">=0.69" + redux: ^5.0.0 peerDependenciesMeta: "@types/react": optional: true - "@types/react-dom": - optional: true - react-dom: - optional: true react-native: optional: true redux: optional: true - checksum: 64c8be2765568dc66a3c442a41dd0ed74fe048d5ceb7a4fe72e5bac3d3687996a7115f57b5156af7406521087065a0e60f9194318c8ca99c55e9ce48558980ce + checksum: 23af10014b129aeb051de729bde01de21175170b860deefb7ad83483feab5816253f770a4cea93333fc22a53ac9ac699b27f5c3705c388dab53dbcb2906a571a languageName: node linkType: hard @@ -14039,16 +14036,16 @@ __metadata: languageName: node linkType: hard -"redux-thunk@npm:^2.4.2": - version: 2.4.2 - resolution: "redux-thunk@npm:2.4.2" +"redux-thunk@npm:^3.1.0": + version: 3.1.0 + resolution: "redux-thunk@npm:3.1.0" peerDependencies: - redux: ^4 - checksum: e202d6ef7dfa7df08ed24cb221aa89d6c84dbaa7d65fe90dbd8e826d0c10d801f48388f9a7598a4fd970ecbc93d335014570a61ca7bc8bf569eab5de77b31a3c + redux: ^5.0.0 + checksum: 21557f6a30e1b2e3e470933247e51749be7f1d5a9620069a3125778675ce4d178d84bdee3e2a0903427a5c429e3aeec6d4df57897faf93eb83455bc1ef7b66fd languageName: node linkType: hard -"redux@npm:^4.0.0, redux@npm:^4.2.1": +"redux@npm:^4.0.0": version: 4.2.1 resolution: "redux@npm:4.2.1" dependencies: @@ -14057,6 +14054,13 @@ __metadata: languageName: node linkType: hard +"redux@npm:^5.0.0": + version: 5.0.1 + resolution: "redux@npm:5.0.1" + checksum: b10c28357194f38e7d53b760ed5e64faa317cc63de1fb95bc5d9e127fab956392344368c357b8e7a9bedb0c35b111e7efa522210cfdc3b3c75e5074718e9069c + languageName: node + linkType: hard + "reflect.getprototypeof@npm:^1.0.4": version: 1.0.4 resolution: "reflect.getprototypeof@npm:1.0.4" @@ -14226,10 +14230,10 @@ __metadata: languageName: node linkType: hard -"reselect@npm:^4.1.8": - version: 4.1.8 - resolution: "reselect@npm:4.1.8" - checksum: 06a305a504affcbb67dd0561ddc8306b35796199c7e15b38934c80606938a021eadcf68cfd58e7bb5e17786601c37602a3362a4665c7bf0a96c1041ceee9d0b7 +"reselect@npm:^5.0.1": + version: 5.0.1 + resolution: "reselect@npm:5.0.1" + checksum: 0724b4555cd6411849de334a75177780f127af849eb71c4b709966d07ade8090d125c0c926dc6cf936866d23ebadda6aad1da93cd8340525323b889f25d56d51 languageName: node linkType: hard