From b413d5368161a695e4f54eee33d3154324151aa0 Mon Sep 17 00:00:00 2001 From: Ilan Gold Date: Thu, 21 Nov 2024 11:21:25 +0100 Subject: [PATCH] (chore): upgrade zustand (#840) * (chore): upgrade zustand * (fix): lint --- pnpm-lock.yaml | 34 +++++++++++++++---- sites/avivator/package.json | 2 +- .../src/components/Controller/Controller.jsx | 12 +++---- .../Controller/components/AddChannel.jsx | 12 +++---- .../Controller/components/CameraOptions.jsx | 12 +++---- .../components/ChannelController.jsx | 9 +++-- .../components/GlobalSelectionSlider.jsx | 5 ++- .../Controller/components/LensSelect.jsx | 9 +++-- .../components/Controller/components/Menu.jsx | 12 +++---- .../Controller/components/PanLockToggle.jsx | 5 ++- .../components/PictureInPictureToggle.jsx | 12 ++++--- .../components/RenderingModeSelect.jsx | 5 ++- .../components/SideBySideToggle.jsx | 7 ++-- .../Controller/components/Slicer.jsx | 5 ++- .../Controller/components/VolumeButton.jsx | 10 +++--- .../Controller/components/ZoomLockToggle.jsx | 5 ++- sites/avivator/src/components/Footer.jsx | 5 ++- .../src/components/Snackbars/Snackbars.jsx | 7 ++-- sites/avivator/src/components/Viewer.jsx | 15 ++++---- sites/avivator/src/hooks.js | 12 ++++--- sites/avivator/src/state.js | 11 +++--- 21 files changed, 107 insertions(+), 99 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 69846eaa8..65a9607a2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -326,8 +326,8 @@ importers: specifier: ^14.2.3 version: 14.2.3(react@18.3.1) zustand: - specifier: ^3.4.1 - version: 3.7.2(react@18.3.1) + specifier: ^5.0.1 + version: 5.0.1(react@18.3.1)(use-sync-external-store@1.2.2(react@18.3.1)) devDependencies: '@vitejs/plugin-react': specifier: ^4.2.1 @@ -4734,6 +4734,11 @@ packages: urlpattern-polyfill@10.0.0: resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} + use-sync-external-store@1.2.2: + resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + utf8-stream@0.0.0: resolution: {integrity: sha512-X92xJPYQcFbRH4IaCH7zUEc8JLgGlIum7JFvo3AVTCaxMrJKEMrpoEkmE3P2NV0nALyM/rDHqIW628jt+BCO+w==} @@ -4938,14 +4943,23 @@ packages: zstddec@0.1.0: resolution: {integrity: sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==} - zustand@3.7.2: - resolution: {integrity: sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==} - engines: {node: '>=12.7.0'} + zustand@5.0.1: + resolution: {integrity: sha512-pRET7Lao2z+n5R/HduXMio35TncTlSW68WsYBq2Lg1ASspsNGjpwLAsij3RpouyV6+kHMwwwzP0bZPD70/Jx/w==} + engines: {node: '>=12.20.0'} peerDependencies: - react: '>=16.8' + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true react: optional: true + use-sync-external-store: + optional: true zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -10092,6 +10106,11 @@ snapshots: urlpattern-polyfill@10.0.0: {} + use-sync-external-store@1.2.2(react@18.3.1): + dependencies: + react: 18.3.1 + optional: true + utf8-stream@0.0.0: dependencies: readable-stream: 1.0.34 @@ -10300,8 +10319,9 @@ snapshots: zstddec@0.1.0: {} - zustand@3.7.2(react@18.3.1): + zustand@5.0.1(react@18.3.1)(use-sync-external-store@1.2.2(react@18.3.1)): optionalDependencies: react: 18.3.1 + use-sync-external-store: 1.2.2(react@18.3.1) zwitch@2.0.4: {} diff --git a/sites/avivator/package.json b/sites/avivator/package.json index aa869ce02..b26aee69b 100644 --- a/sites/avivator/package.json +++ b/sites/avivator/package.json @@ -18,7 +18,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", - "zustand": "^3.4.1" + "zustand": "^5.0.1" }, "devDependencies": { "@vitejs/plugin-react": "^4.2.1", diff --git a/sites/avivator/src/components/Controller/Controller.jsx b/sites/avivator/src/components/Controller/Controller.jsx index ec353e42f..7c6a3ad6c 100644 --- a/sites/avivator/src/components/Controller/Controller.jsx +++ b/sites/avivator/src/components/Controller/Controller.jsx @@ -4,7 +4,7 @@ import Grid from '@material-ui/core/Grid'; import Tab from '@material-ui/core/Tab'; import Tabs from '@material-ui/core/Tabs'; import React, { useState } from 'react'; -import shallow from 'zustand/shallow'; +import { useShallow } from 'zustand/shallow'; import { GLOBAL_SLIDER_DIMENSION_FIELDS } from '../../constants'; import { @@ -58,7 +58,7 @@ const Controller = () => { toggleIsOnSetter, removeChannel ] = useChannelsStore( - store => [ + useShallow(store => [ store.channelsVisible, store.contrastLimits, store.colors, @@ -68,8 +68,7 @@ const Controller = () => { store.setPropertiesForChannel, store.toggleIsOn, store.removeChannel - ], - shallow + ]) ); const loader = useLoader(); @@ -86,7 +85,7 @@ const Controller = () => { pixelValues, isViewerLoading ] = useViewerStore( - store => [ + useShallow(store => [ store.channelOptions, store.useLinkedView, store.use3d, @@ -97,8 +96,7 @@ const Controller = () => { store.removeIsChannelLoading, store.pixelValues, store.isViewerLoading - ], - shallow + ]) ); const metadata = useMetadata(); const viewSize = useWindowSize(); diff --git a/sites/avivator/src/components/Controller/components/AddChannel.jsx b/sites/avivator/src/components/Controller/components/AddChannel.jsx index 899e6f9db..e4fe0304b 100644 --- a/sites/avivator/src/components/Controller/components/AddChannel.jsx +++ b/sites/avivator/src/components/Controller/components/AddChannel.jsx @@ -1,7 +1,7 @@ import Button from '@material-ui/core/Button'; import AddIcon from '@material-ui/icons/Add'; import React, { useCallback } from 'react'; -import shallow from 'zustand/shallow'; +import { useShallow } from 'zustand/shallow'; import { COLOR_PALLETE, MAX_CHANNELS } from '../../../constants'; import { @@ -21,22 +21,20 @@ const AddChannel = () => { setIsChannelLoading, addIsChannelLoading ] = useViewerStore( - store => [ + useShallow(store => [ store.globalSelection, store.isViewerLoading, store.use3d, store.setIsChannelLoading, store.addIsChannelLoading - ], - shallow + ]) ); const [selections, addChannel, setPropertiesForChannel] = useChannelsStore( - store => [ + useShallow(store => [ store.selections, store.addChannel, store.setPropertiesForChannel - ], - shallow + ]) ); const loader = useLoader(); const metadata = useMetadata(); diff --git a/sites/avivator/src/components/Controller/components/CameraOptions.jsx b/sites/avivator/src/components/Controller/components/CameraOptions.jsx index b95c62ec1..de8ef2fc0 100644 --- a/sites/avivator/src/components/Controller/components/CameraOptions.jsx +++ b/sites/avivator/src/components/Controller/components/CameraOptions.jsx @@ -4,7 +4,7 @@ import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; import { createStyles, makeStyles } from '@material-ui/core/styles'; import React from 'react'; -import shallow from 'zustand/shallow'; +import { useShallow } from 'zustand/shallow'; import { getDefaultInitialViewState } from '@hms-dbmi/viv'; import { @@ -29,13 +29,11 @@ const useStyles = makeStyles(theme => const CameraOptions = () => { const loader = useLoader(); const [useFixedAxis, toggleUseFixedAxis] = useImageSettingsStore( - store => [store.useFixedAxis, store.toggleUseFixedAxis], - shallow + useShallow(store => [store.useFixedAxis, store.toggleUseFixedAxis]) + ); + const [viewState, use3d] = useViewerStore( + useShallow(store => [store.viewState, store.use3d]) ); - const [viewState, use3d] = useViewerStore(store => [ - store.viewState, - store.use3d - ]); const { height, width } = useWindowSize(); const classes = useStyles(); const toggleFixedAxisButton = ( diff --git a/sites/avivator/src/components/Controller/components/ChannelController.jsx b/sites/avivator/src/components/Controller/components/ChannelController.jsx index 45cd956ab..e094f9f97 100644 --- a/sites/avivator/src/components/Controller/components/ChannelController.jsx +++ b/sites/avivator/src/components/Controller/components/ChannelController.jsx @@ -8,7 +8,7 @@ import IconButton from '@material-ui/core/IconButton'; import Select from '@material-ui/core/Select'; import Slider from '@material-ui/core/Slider'; import HighlightOffIcon from '@material-ui/icons/HighlightOff'; -import shallow from 'zustand/shallow'; +import { useShallow } from 'zustand/shallow'; import { FILL_PIXEL_VALUE } from '../../../constants'; import { @@ -60,8 +60,11 @@ function ChannelController({ const loader = useLoader(); const colormap = useImageSettingsStore(store => store.colormap); const [channelOptions, useLinkedView, use3d] = useViewerStore( - store => [store.channelOptions, store.useLinkedView, store.use3d], - shallow + useShallow(store => [ + store.channelOptions, + store.useLinkedView, + store.use3d + ]) ); const rgbColor = toRgb(colormap, color); const getMinMax = ({ domain: d, mode, loader: l }) => { diff --git a/sites/avivator/src/components/Controller/components/GlobalSelectionSlider.jsx b/sites/avivator/src/components/Controller/components/GlobalSelectionSlider.jsx index 9134cc01e..1dee92884 100644 --- a/sites/avivator/src/components/Controller/components/GlobalSelectionSlider.jsx +++ b/sites/avivator/src/components/Controller/components/GlobalSelectionSlider.jsx @@ -3,7 +3,7 @@ import Slider from '@material-ui/core/Slider'; import debounce from 'lodash/debounce'; import React from 'react'; import { unstable_batchedUpdates } from 'react-dom'; -import shallow from 'zustand/shallow'; +import { useShallow } from 'zustand/shallow'; import { useChannelsStore, @@ -16,8 +16,7 @@ import { getMultiSelectionStats, range } from '../../../utils'; export default function GlobalSelectionSlider(props) { const { size, label } = props; const [selections, setPropertiesForChannel] = useChannelsStore( - store => [store.selections, store.setPropertiesForChannel], - shallow + useShallow(store => [store.selections, store.setPropertiesForChannel]) ); const loader = useLoader(); const globalSelection = useViewerStore(store => store.globalSelection); diff --git a/sites/avivator/src/components/Controller/components/LensSelect.jsx b/sites/avivator/src/components/Controller/components/LensSelect.jsx index 1cc110270..32b5155cf 100644 --- a/sites/avivator/src/components/Controller/components/LensSelect.jsx +++ b/sites/avivator/src/components/Controller/components/LensSelect.jsx @@ -3,7 +3,7 @@ import React from 'react'; import Checkbox from '@material-ui/core/Checkbox'; import Grid from '@material-ui/core/Grid'; import Select from '@material-ui/core/Select'; -import shallow from 'zustand/shallow'; +import { useShallow } from 'zustand/shallow'; import { useChannelsStore, @@ -14,8 +14,11 @@ import { function LensSelect() { const selections = useChannelsStore(store => store.selections); const [lensEnabled, toggleLensEnabled, lensSelection] = useImageSettingsStore( - store => [store.lensEnabled, store.toggleLensEnabled, store.lensSelection], - shallow + useShallow(store => [ + store.lensEnabled, + store.toggleLensEnabled, + store.lensSelection + ]) ); const channelOptions = useViewerStore(store => store.channelOptions); const currChannelIndices = selections.map(sel => sel.c); diff --git a/sites/avivator/src/components/Controller/components/Menu.jsx b/sites/avivator/src/components/Controller/components/Menu.jsx index ffa6f18cf..c11c8ae2b 100644 --- a/sites/avivator/src/components/Controller/components/Menu.jsx +++ b/sites/avivator/src/components/Controller/components/Menu.jsx @@ -13,7 +13,7 @@ import { makeStyles } from '@material-ui/core/styles'; import InfoIcon from '@material-ui/icons/Info'; import SettingsIcon from '@material-ui/icons/Settings'; import React, { useState, useReducer, useRef, useEffect } from 'react'; -import shallow from 'zustand/shallow'; +import { useShallow } from 'zustand/shallow'; import { useChannelsStore, useViewerStore } from '../../../state'; import { getNameFromUrl, isMobileOrTablet } from '../../../utils'; @@ -53,10 +53,9 @@ const useStyles = makeStyles(theme => ({ function Header(props) { const image = useChannelsStore(store => store.image); - const [source, metadata] = useViewerStore(store => [ - store.source, - store.metadata - ]); + const [source, metadata] = useViewerStore( + useShallow(store => [store.source, store.metadata]) + ); const handleSubmitNewUrl = (event, newUrl) => { event.preventDefault(); const newSource = { @@ -159,8 +158,7 @@ function Header(props) { function Menu({ children, ...props }) { const classes = useStyles(props); const [isControllerOn, toggleIsControllerOn] = useViewerStore( - store => [store.isControllerOn, store.toggleIsControllerOn], - shallow + useShallow(store => [store.isControllerOn, store.toggleIsControllerOn]) ); return isControllerOn ? ( diff --git a/sites/avivator/src/components/Controller/components/PanLockToggle.jsx b/sites/avivator/src/components/Controller/components/PanLockToggle.jsx index 00a7132a4..e96f5628c 100644 --- a/sites/avivator/src/components/Controller/components/PanLockToggle.jsx +++ b/sites/avivator/src/components/Controller/components/PanLockToggle.jsx @@ -1,13 +1,12 @@ import Button from '@material-ui/core/Button'; import React from 'react'; -import shallow from 'zustand/shallow'; +import { useShallow } from 'zustand/shallow'; import { useImageSettingsStore, useViewerStore } from '../../../state'; const PanLockToggle = () => { const [togglePanLock, panLock] = useImageSettingsStore( - store => [store.togglePanLock, store.panLock], - shallow + useShallow(store => [store.togglePanLock, store.panLock]) ); const isViewerLoading = useViewerStore(store => store.isViewerLoading); return ( diff --git a/sites/avivator/src/components/Controller/components/PictureInPictureToggle.jsx b/sites/avivator/src/components/Controller/components/PictureInPictureToggle.jsx index 838a743a5..0217c4a05 100644 --- a/sites/avivator/src/components/Controller/components/PictureInPictureToggle.jsx +++ b/sites/avivator/src/components/Controller/components/PictureInPictureToggle.jsx @@ -1,17 +1,19 @@ import Button from '@material-ui/core/Button'; import React from 'react'; -import shallow from 'zustand/shallow'; +import { useShallow } from 'zustand/shallow'; import { useImageSettingsStore, useViewerStore } from '../../../state'; const PictureInPictureToggle = () => { const [isOverviewOn, toggleIsOverviewOn] = useImageSettingsStore( - store => [store.isOverviewOn, store.toggleIsOverviewOn], - shallow + useShallow(store => [store.isOverviewOn, store.toggleIsOverviewOn]) ); const [isViewerLoading, useLinkedView, use3d] = useViewerStore( - store => [store.isViewerLoading, store.useLinkedView, store.use3d], - shallow + useShallow(store => [ + store.isViewerLoading, + store.useLinkedView, + store.use3d + ]) ); return (