diff --git a/.yarn/releases/yarn-3.8.7.cjs b/.yarn/releases/yarn-3.8.7.cjs old mode 100755 new mode 100644 diff --git a/docs/package.json b/docs/package.json index 032793171e..3ced67a027 100644 --- a/docs/package.json +++ b/docs/package.json @@ -32,6 +32,7 @@ "@remix-run/serve": "2.15.2", "@remix-run/server-runtime": "2.15.2", "@supabase/supabase-js": "2.47.10", + "@use-gesture/react": "^10.3.1", "@vanilla-extract/css": "1.17.0", "@vanilla-extract/dynamic": "2.1.2", "@vanilla-extract/recipes": "0.5.5", @@ -44,6 +45,7 @@ "react": "18.3.1", "react-dom": "18.3.1", "react-select": "5.9.0", + "react-use-measure": "^2.1.1", "zod": "3.24.1" }, "devDependencies": { diff --git a/package.json b/package.json index 6429c5e7f2..7d62e35c4d 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@changesets/cli": "2.27.11", "@commitlint/cli": "19.6.1", "@commitlint/config-conventional": "19.6.0", - "@react-three/fiber": "8.17.10", + "@react-three/fiber": "^9.0.4", "@remix-run/dev": "2.15.2", "@simonsmith/cypress-image-snapshot": "9.1.0", "@swc/core": "1.10.4", @@ -79,8 +79,8 @@ "@types/jest": "29.5.14", "@types/lodash.clamp": "4.0.9", "@types/lodash.shuffle": "4.2.9", - "@types/react": "18.3.18", - "@types/react-dom": "18.3.5", + "@types/react": "19.0.2", + "@types/react-dom": "19.0.2", "@types/react-lazyload": "3.2.3", "@types/react-native": "0.73.0", "@types/styled-components": "5.1.34", @@ -95,8 +95,8 @@ "mock-raf": "npm:@react-spring/mock-raf@1.1.1", "prettier": "3.4.2", "pretty-quick": "4.0.0", - "react": "18.3.1", - "react-dom": "18.3.1", + "react": "19.0.0", + "react-dom": "19.0.0", "react-konva": "18.2.10", "react-native": "0.76.5", "react-zdog": "1.2.2", diff --git a/packages/animated/src/withAnimated.tsx b/packages/animated/src/withAnimated.tsx index ba715d8dde..cbfb3715a5 100644 --- a/packages/animated/src/withAnimated.tsx +++ b/packages/animated/src/withAnimated.tsx @@ -1,5 +1,12 @@ import * as React from 'react' -import { forwardRef, useRef, Ref, useCallback, useEffect } from 'react' +import { + forwardRef, + useRef, + Ref, + useCallback, + useEffect, + MutableRefObject, +} from 'react' import { is, each, @@ -66,7 +73,10 @@ export const withAnimated = (Component: any, host: HostConfig) => { const observer = new PropsObserver(callback, deps) - const observerRef = useRef() + // NOTE: useRef is bugged as immutable in 18.3 types + const observerRef = useRef( + null + ) as MutableRefObject useIsomorphicLayoutEffect(() => { observerRef.current = observer diff --git a/packages/core/src/SpringContext.tsx b/packages/core/src/SpringContext.tsx index 8e0a48d6fe..0667c310a5 100644 --- a/packages/core/src/SpringContext.tsx +++ b/packages/core/src/SpringContext.tsx @@ -13,33 +13,54 @@ export interface SpringContext { immediate?: boolean } -export const SpringContext = ({ - children, - ...props -}: PropsWithChildren) => { - const inherited = useContext(ctx) +export const SpringContext = makeRenderableContext< + SpringContext, + PropsWithChildren +>( + Context => + ({ children, ...props }) => { + const inherited = useContext(Context) - // Inherited values are dominant when truthy. - const pause = props.pause || !!inherited.pause, - immediate = props.immediate || !!inherited.immediate + // Inherited values are dominant when truthy. + const pause = props.pause || !!inherited.pause + const immediate = props.immediate || !!inherited.immediate - // Memoize the context to avoid unwanted renders. - props = useMemoOne(() => ({ pause, immediate }), [pause, immediate]) + // Memoize the context to avoid unwanted renders. + props = useMemoOne(() => ({ pause, immediate }), [pause, immediate]) - const { Provider } = ctx - return {children} + return {children} + }, + {} as SpringContext +) + +interface RenderableContext extends React.ProviderExoticComponent

{ + Provider: RenderableContext + Consumer: React.Consumer + displayName?: string } -const ctx = makeContext(SpringContext, {} as SpringContext) +/** Make the `target` compatible with `useContext` */ +function makeRenderableContext( + target: (context: React.Context) => React.FunctionComponent

, + init: T +): RenderableContext { + let context = React.createContext(init) + context = Object.assign(target(context), context) + + // https://github.com/facebook/react/pull/28226 + if ('_context' in context.Provider) { + context.Provider._context = context + } else { + // @ts-ignore React 18 types disallow this + context.Provider = context + } -// Allow `useContext(SpringContext)` in TypeScript. -SpringContext.Provider = ctx.Provider -SpringContext.Consumer = ctx.Consumer + if ('_context' in context.Consumer) { + context.Consumer._context = context + } else { + // @ts-expect-error + context.Consumer = context + } -/** Make the `target` compatible with `useContext` */ -function makeContext(target: any, init: T): React.Context { - Object.assign(target, React.createContext(init)) - target.Provider._context = target - target.Consumer._context = target - return target + return context as unknown as RenderableContext } diff --git a/packages/core/src/components/Spring.tsx b/packages/core/src/components/Spring.tsx index e835c2d482..c902dd2e64 100644 --- a/packages/core/src/components/Spring.tsx +++ b/packages/core/src/components/Spring.tsx @@ -1,3 +1,4 @@ +import { JSX } from 'react' import { NoInfer, UnknownProps } from '@react-spring/types' import { useSpring, UseSpringProps } from '../hooks/useSpring' import { SpringValues, SpringToFn, SpringChain } from '../types' diff --git a/packages/core/src/components/Transition.tsx b/packages/core/src/components/Transition.tsx index 7b2a3bd337..ce7fbe7203 100644 --- a/packages/core/src/components/Transition.tsx +++ b/packages/core/src/components/Transition.tsx @@ -1,3 +1,4 @@ +import { JSX } from 'react' import { Valid } from '../types/common' import { TransitionComponentProps } from '../types' import { useTransition } from '../hooks' diff --git a/packages/core/src/hooks/useInView.ts b/packages/core/src/hooks/useInView.ts index 7d26d2c3d2..90dc6c9067 100644 --- a/packages/core/src/hooks/useInView.ts +++ b/packages/core/src/hooks/useInView.ts @@ -35,7 +35,7 @@ export function useInView( args?: IntersectionArgs ) { const [isInView, setIsInView] = useState(false) - const ref = useRef() + const ref = useRef(null) const propsFn = is.fun(props) && props diff --git a/packages/core/src/hooks/useSpring.test.tsx b/packages/core/src/hooks/useSpring.test.tsx index c5bd8892c8..68935ce676 100644 --- a/packages/core/src/hooks/useSpring.test.tsx +++ b/packages/core/src/hooks/useSpring.test.tsx @@ -115,7 +115,7 @@ interface TestContext extends SpringContext { } function createUpdater(Component: React.ComponentType<{ args: [any, any?] }>) { - let prevElem: JSX.Element | undefined + let prevElem: React.JSX.Element | undefined let result: RenderResult | undefined const context: TestContext = { @@ -139,7 +139,7 @@ function createUpdater(Component: React.ComponentType<{ args: [any, any?] }>) { } }) - function renderWithContext(elem: JSX.Element) { + function renderWithContext(elem: React.JSX.Element) { const wrapped = {elem} if (result) result.rerender(wrapped) else result = render(wrapped) diff --git a/packages/core/src/hooks/useSprings.ts b/packages/core/src/hooks/useSprings.ts index a1729fda9c..ddb8d2f3e4 100644 --- a/packages/core/src/hooks/useSprings.ts +++ b/packages/core/src/hooks/useSprings.ts @@ -128,7 +128,8 @@ export function useSprings( ) const ctrls = useRef([...state.ctrls]) - const updates: any[] = [] + const updates = useRef(null!) + updates.current ??= [] // Cache old controllers to dispose in the commit phase. const prevLength = usePrev(length) || 0 @@ -164,7 +165,7 @@ export function useSprings( : (props as any)[i] if (update) { - updates[i] = declareUpdate(update) + updates.current[i] = declareUpdate(update) } } } @@ -172,7 +173,9 @@ export function useSprings( // New springs are created during render so users can pass them to // their animated components, but new springs aren't cached until the // commit phase (see the `useIsomorphicLayoutEffect` callback below). - const springs = ctrls.current.map((ctrl, i) => getSprings(ctrl, updates[i])) + const springs = ctrls.current.map((ctrl, i) => + getSprings(ctrl, updates.current[i]) + ) const context = useContext(SpringContext) const prevContext = usePrev(context) @@ -202,7 +205,7 @@ export function useSprings( } // Apply updates created during render. - const update = updates[i] + const update = updates.current[i] if (update) { // Update the injected ref if needed. replaceRef(ctrl, update.ref) @@ -214,6 +217,8 @@ export function useSprings( } else { ctrl.start(update) } + + updates.current[i] = null } }) }) diff --git a/packages/core/src/types/transition.ts b/packages/core/src/types/transition.ts index 8fe1344e0a..7ae3acf69e 100644 --- a/packages/core/src/types/transition.ts +++ b/packages/core/src/types/transition.ts @@ -1,4 +1,4 @@ -import { ReactNode } from 'react' +import { ReactNode, JSX } from 'react' import { Lookup, ObjectFromUnion, diff --git a/packages/core/test/setup.ts b/packages/core/test/setup.ts index 3b9af122fa..9a5ca59e8e 100644 --- a/packages/core/test/setup.ts +++ b/packages/core/test/setup.ts @@ -60,9 +60,6 @@ beforeEach(() => { requestAnimationFrame: global.mockRaf.raf, colors, skipAnimation: false, - // This lets our useTransition hook force its component - // to update from within an "onRest" handler. - batchedUpdates: act, }) }) @@ -138,7 +135,7 @@ global.advanceUntil = async test => { willAdvance: observe, }) - jest.advanceTimersByTime(1000 / 60) + await act(() => jest.advanceTimersByTimeAsync(1000 / 60)) global.mockRaf.step() // Stop observing after the frame is processed. @@ -147,7 +144,7 @@ global.advanceUntil = async test => { } // Ensure pending effects are flushed. - await flushMicroTasks() + await act(() => flushMicroTasks()) // Prevent infinite recursion. if (++steps > 1e3) { diff --git a/packages/parallax/src/index.tsx b/packages/parallax/src/index.tsx index 74e05932a5..9594c852bd 100644 --- a/packages/parallax/src/index.tsx +++ b/packages/parallax/src/index.tsx @@ -143,7 +143,7 @@ export const ParallaxLayer = React.memo( React.useImperativeHandle(ref, () => layer) - const layerRef = useRef() + const layerRef = useRef(null) const setSticky = (height: number, scrollTop: number) => { const start = layer.sticky!.start! * height @@ -229,8 +229,8 @@ export const Parallax = React.memo( ...rest } = props - const containerRef = useRef() - const contentRef = useRef() + const containerRef = useRef(null) + const contentRef = useRef(null) const state: IParallax = useMemoOne( () => ({ diff --git a/packages/shared/src/hooks/useMemoOne.ts b/packages/shared/src/hooks/useMemoOne.ts index 4d02743845..7d5cef54f1 100644 --- a/packages/shared/src/hooks/useMemoOne.ts +++ b/packages/shared/src/hooks/useMemoOne.ts @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react' +import { useEffect, useRef, useState, MutableRefObject } from 'react' type Cache = { inputs?: any[] @@ -14,7 +14,8 @@ export function useMemoOne(getResult: () => T, inputs?: any[]): T { }) ) - const committed = useRef>() + // NOTE: useRef is bugged as immutable in 18.3 types + const committed = useRef>(null) as MutableRefObject | null> const prevCache = committed.current let cache = prevCache diff --git a/packages/shared/src/hooks/usePrev.ts b/packages/shared/src/hooks/usePrev.ts index 9c97e064c8..bf44a12d3a 100644 --- a/packages/shared/src/hooks/usePrev.ts +++ b/packages/shared/src/hooks/usePrev.ts @@ -2,7 +2,7 @@ import { useEffect, useRef } from 'react' /** Use a value from the previous render */ export function usePrev(value: T): T | undefined { - const prevRef = useRef() + const prevRef = useRef(null) useEffect(() => { prevRef.current = value }) diff --git a/targets/three/src/animated.ts b/targets/three/src/animated.ts index 39f100b5e4..230837381b 100644 --- a/targets/three/src/animated.ts +++ b/targets/three/src/animated.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { CSSProperties, ForwardRefExoticComponent, FC } from 'react' +import { CSSProperties, ForwardRefExoticComponent, FC, JSX } from 'react' import { AssignableKeys, ComponentPropsWithRef, diff --git a/targets/three/src/index.ts b/targets/three/src/index.ts index 7840ae51ad..a8c4a9410a 100644 --- a/targets/three/src/index.ts +++ b/targets/three/src/index.ts @@ -19,7 +19,7 @@ addEffect(() => { }) const host = createHost(primitives, { - // @ts-expect-error r3f related + // @ts-ignore related to R3F v8 applyAnimatedValues: applyProps, }) diff --git a/targets/three/src/primitives.ts b/targets/three/src/primitives.ts index 16c36921b0..228d5bf1bc 100644 --- a/targets/three/src/primitives.ts +++ b/targets/three/src/primitives.ts @@ -1,5 +1,5 @@ import * as THREE from 'three' -import '@react-three/fiber' +import { JSX } from 'react' export type Primitives = keyof JSX.IntrinsicElements diff --git a/targets/web/src/primitives.ts b/targets/web/src/primitives.ts index a77a1f3d70..23edb245fa 100644 --- a/targets/web/src/primitives.ts +++ b/targets/web/src/primitives.ts @@ -1,3 +1,5 @@ +import { JSX } from 'react' + export type Primitives = keyof JSX.IntrinsicElements export const primitives: Primitives[] = [ 'a', diff --git a/yarn.lock b/yarn.lock index c0fdc04aab..93afb4a270 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4682,6 +4682,7 @@ __metadata: "@remix-run/serve": 2.15.2 "@remix-run/server-runtime": 2.15.2 "@supabase/supabase-js": 2.47.10 + "@use-gesture/react": ^10.3.1 "@vanilla-extract/css": 1.17.0 "@vanilla-extract/dynamic": 2.1.2 "@vanilla-extract/recipes": 0.5.5 @@ -4702,6 +4703,7 @@ __metadata: react: 18.3.1 react-dom: 18.3.1 react-select: 5.9.0 + react-use-measure: ^2.1.1 refractor: 4.8.1 rehype-autolink-headings: 7.1.0 rehype-parse: 9.0.1 @@ -4908,6 +4910,48 @@ __metadata: languageName: node linkType: hard +"@react-three/fiber@npm:^9.0.4": + version: 9.0.4 + resolution: "@react-three/fiber@npm:9.0.4" + dependencies: + "@babel/runtime": ^7.17.8 + "@types/react-reconciler": ^0.28.9 + "@types/webxr": "*" + base64-js: ^1.5.1 + buffer: ^6.0.3 + its-fine: ^2.0.0 + react-reconciler: ^0.31.0 + react-use-measure: ^2.1.7 + scheduler: ^0.25.0 + suspend-react: ^0.1.3 + use-sync-external-store: ^1.4.0 + zustand: ^5.0.3 + peerDependencies: + expo: ">=43.0" + expo-asset: ">=8.4" + expo-file-system: ">=11.0" + expo-gl: ">=11.0" + react: ^19.0.0 + react-dom: ^19.0.0 + react-native: ">=0.78" + three: ">=0.156" + peerDependenciesMeta: + expo: + optional: true + expo-asset: + optional: true + expo-file-system: + optional: true + expo-gl: + optional: true + react-dom: + optional: true + react-native: + optional: true + checksum: 222d90d1d108c5abd0b568222835062e0add08a49ee5fadf23681a91251fa7f8c1b048854c21169a25f162abf6fe6371858040307a1e8fbcc917614e22204dd2 + languageName: node + linkType: hard + "@remix-run/dev@npm:2.15.2": version: 2.15.2 resolution: "@remix-run/dev@npm:2.15.2" @@ -6047,12 +6091,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:18.3.5": - version: 18.3.5 - resolution: "@types/react-dom@npm:18.3.5" +"@types/react-dom@npm:19.0.2": + version: 19.0.2 + resolution: "@types/react-dom@npm:19.0.2" peerDependencies: - "@types/react": ^18.0.0 - checksum: 95c757684f71e761515c5a11299e5feec550c72bb52975487f360e6f0d359b26454c26eaf2ce45dd22748205aa9b2c2fe0abe7005ebcbd233a7615283ac39a7d + "@types/react": ^19.0.0 + checksum: d2ae81ec0b8eee7a4bf31918796fdaa34e8db68f69682163bc212d759de76783e6ffcc02c02722dcf508429067148841e6da81414cc730ca2a28c9c2b350c880 languageName: node linkType: hard @@ -6092,6 +6136,15 @@ __metadata: languageName: node linkType: hard +"@types/react-reconciler@npm:^0.28.9": + version: 0.28.9 + resolution: "@types/react-reconciler@npm:0.28.9" + peerDependencies: + "@types/react": "*" + checksum: 06257f693c7b148a4258c0d0a958288116100014e7b3c21ceaea2d55a668c71718f79b4105a9a0f35b480f3729e46960b40026d685719f9386b4ed63108dda09 + languageName: node + linkType: hard + "@types/react-transition-group@npm:^4.4.0": version: 4.4.10 resolution: "@types/react-transition-group@npm:4.4.10" @@ -6101,7 +6154,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:18.3.18": +"@types/react@npm:*": version: 18.3.18 resolution: "@types/react@npm:18.3.18" dependencies: @@ -6111,6 +6164,15 @@ __metadata: languageName: node linkType: hard +"@types/react@npm:19.0.2": + version: 19.0.2 + resolution: "@types/react@npm:19.0.2" + dependencies: + csstype: ^3.0.2 + checksum: 2f12c2a84b778283884d41560c723d815153d88c56cacf25c0166329e9099c35c82c602a21d8831a381e2ef5574434ebd7bf09a636fe073558919474b0b3c9ed + languageName: node + linkType: hard + "@types/semver@npm:^7.5.0": version: 7.5.6 resolution: "@types/semver@npm:7.5.6" @@ -12519,6 +12581,17 @@ __metadata: languageName: node linkType: hard +"its-fine@npm:^2.0.0": + version: 2.0.0 + resolution: "its-fine@npm:2.0.0" + dependencies: + "@types/react-reconciler": ^0.28.9 + peerDependencies: + react: ^19.0.0 + checksum: 887ff10d8dfe8558683d5f68ad963c72a28c6df027c5039de7ec57978e5071c564ef4b00b14ef41e7706e5839a5584cbd480a79a3880f78d7ff826931e5dc22a + languageName: node + linkType: hard + "jackspeak@npm:^3.1.2": version: 3.4.3 resolution: "jackspeak@npm:3.4.3" @@ -16886,6 +16959,17 @@ __metadata: languageName: node linkType: hard +"react-dom@npm:19.0.0": + version: 19.0.0 + resolution: "react-dom@npm:19.0.0" + dependencies: + scheduler: ^0.25.0 + peerDependencies: + react: ^19.0.0 + checksum: 009cc6e575263a0d1906f9dd4aa6532d2d3d0d71e4c2b7777c8fe4de585fa06b5b77cdc2e0fbaa2f3a4a5e5d3305c189ba152153f358ee7da4d9d9ba5d3a8975 + languageName: node + linkType: hard + "react-dropzone@npm:^12.0.0": version: 12.1.0 resolution: "react-dropzone@npm:12.1.0" @@ -17013,6 +17097,17 @@ __metadata: languageName: node linkType: hard +"react-reconciler@npm:^0.31.0": + version: 0.31.0 + resolution: "react-reconciler@npm:0.31.0" + dependencies: + scheduler: ^0.25.0 + peerDependencies: + react: ^19.0.0 + checksum: 820c4e4003c5615849bf0cda97d8a55b99af2bb59cc0825882b727f0ad0c4bf4581bb3d25e00beca1164203dbc172f0a8c4725e7aa2fb85e025938722384a84e + languageName: node + linkType: hard + "react-reconciler@npm:~0.29.0": version: 0.29.0 resolution: "react-reconciler@npm:0.29.0" @@ -17125,7 +17220,7 @@ __metadata: "@changesets/cli": 2.27.11 "@commitlint/cli": 19.6.1 "@commitlint/config-conventional": 19.6.0 - "@react-three/fiber": 8.17.10 + "@react-three/fiber": ^9.0.4 "@remix-run/dev": 2.15.2 "@simonsmith/cypress-image-snapshot": 9.1.0 "@swc/core": 1.10.4 @@ -17138,8 +17233,8 @@ __metadata: "@types/jest": 29.5.14 "@types/lodash.clamp": 4.0.9 "@types/lodash.shuffle": 4.2.9 - "@types/react": 18.3.18 - "@types/react-dom": 18.3.5 + "@types/react": 19.0.2 + "@types/react-dom": 19.0.2 "@types/react-lazyload": 3.2.3 "@types/react-native": 0.73.0 "@types/styled-components": 5.1.34 @@ -17154,8 +17249,8 @@ __metadata: mock-raf: "npm:@react-spring/mock-raf@1.1.1" prettier: 3.4.2 pretty-quick: 4.0.0 - react: 18.3.1 - react-dom: 18.3.1 + react: 19.0.0 + react-dom: 19.0.0 react-konva: 18.2.10 react-native: 0.76.5 react-zdog: 1.2.2 @@ -17226,7 +17321,7 @@ __metadata: languageName: node linkType: hard -"react-use-measure@npm:2.1.1": +"react-use-measure@npm:2.1.1, react-use-measure@npm:^2.1.1": version: 2.1.1 resolution: "react-use-measure@npm:2.1.1" dependencies: @@ -17238,6 +17333,19 @@ __metadata: languageName: node linkType: hard +"react-use-measure@npm:^2.1.7": + version: 2.1.7 + resolution: "react-use-measure@npm:2.1.7" + peerDependencies: + react: ">=16.13" + react-dom: ">=16.13" + peerDependenciesMeta: + react-dom: + optional: true + checksum: 5f00c14cf50b0710cdbd27b63a005be20283099d2fa2723a97f3a1cf0b2daedddd67249520c21e49e95348f56428689f3229c343dcb9ed37da58f9c227d29bee + languageName: node + linkType: hard + "react-zdog@npm:1.2.2": version: 1.2.2 resolution: "react-zdog@npm:1.2.2" @@ -17269,6 +17377,13 @@ __metadata: languageName: node linkType: hard +"react@npm:19.0.0": + version: 19.0.0 + resolution: "react@npm:19.0.0" + checksum: 86de15d85b2465feb40297a90319c325cb07cf27191a361d47bcfe8c6126c973d660125aa67b8f4cbbe39f15a2f32efd0c814e98196d8e5b68c567ba40a399c6 + languageName: node + linkType: hard + "read-yaml-file@npm:^1.1.0": version: 1.1.0 resolution: "read-yaml-file@npm:1.1.0" @@ -18053,6 +18168,13 @@ __metadata: languageName: node linkType: hard +"scheduler@npm:^0.25.0": + version: 0.25.0 + resolution: "scheduler@npm:0.25.0" + checksum: b7bb9fddbf743e521e9aaa5198a03ae823f5e104ebee0cb9ec625392bb7da0baa1c28ab29cee4b1e407a94e76acc6eee91eeb749614f91f853efda2613531566 + languageName: node + linkType: hard + "section-matter@npm:^1.0.0": version: 1.0.0 resolution: "section-matter@npm:1.0.0" @@ -20138,6 +20260,15 @@ __metadata: languageName: node linkType: hard +"use-sync-external-store@npm:^1.4.0": + version: 1.4.0 + resolution: "use-sync-external-store@npm:1.4.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: dc3843a1b59ac8bd01417bd79498d4c688d5df8bf4801be50008ef4bfaacb349058c0b1605b5b43c828e0a2d62722d7e861573b3f31cea77a7f23e8b0fc2f7e3 + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -21075,6 +21206,27 @@ __metadata: languageName: node linkType: hard +"zustand@npm:^5.0.3": + version: 5.0.3 + resolution: "zustand@npm:5.0.3" + peerDependencies: + "@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 + checksum: 72da39ac3017726c3562c615a0f76cee0c9ea678d664f82ee7669f8cb5e153ee81059363473094e4154d73a2935ee3459f6792d1ec9d08d2e72ebe641a16a6ba + languageName: node + linkType: hard + "zwitch@npm:^2.0.0, zwitch@npm:^2.0.4": version: 2.0.4 resolution: "zwitch@npm:2.0.4"