diff --git a/packages/fiber/package.json b/packages/fiber/package.json index aadf297db3..315860aff9 100644 --- a/packages/fiber/package.json +++ b/packages/fiber/package.json @@ -52,7 +52,7 @@ "react-use-measure": "^2.1.1", "scheduler": "^0.21.0", "suspend-react": "^0.1.3", - "zustand": "^3.7.1" + "zustand": "^4.4.1" }, "peerDependencies": { "expo": ">=43.0", diff --git a/packages/fiber/src/core/events.ts b/packages/fiber/src/core/events.ts index 68a8511dbd..415cbffbb4 100644 --- a/packages/fiber/src/core/events.ts +++ b/packages/fiber/src/core/events.ts @@ -1,7 +1,7 @@ import * as THREE from 'three' import { ContinuousEventPriority, DiscreteEventPriority, DefaultEventPriority } from 'react-reconciler/constants' import { getRootState } from './utils' -import type { UseBoundStore } from 'zustand' +import type { StoreApi, UseBoundStore } from 'zustand' import type { Instance } from './renderer' import type { RootState } from './store' import type { Properties } from '../three-types' @@ -152,7 +152,7 @@ function releaseInternalPointerCapture( } } -export function removeInteractivity(store: UseBoundStore, object: THREE.Object3D) { +export function removeInteractivity(store: UseBoundStore>, object: THREE.Object3D) { const { internal } = store.getState() // Removes every trace of an object from the data store internal.interaction = internal.interaction.filter((o) => o !== object) @@ -168,7 +168,7 @@ export function removeInteractivity(store: UseBoundStore, object: THR }) } -export function createEvents(store: UseBoundStore) { +export function createEvents(store: UseBoundStore>) { /** Calculates delta */ function calculateDistance(event: DomEvent) { const { internal } = store.getState() diff --git a/packages/fiber/src/core/hooks.tsx b/packages/fiber/src/core/hooks.tsx index ef06750650..7faf7f50b1 100644 --- a/packages/fiber/src/core/hooks.tsx +++ b/packages/fiber/src/core/hooks.tsx @@ -52,7 +52,7 @@ export function useThree( selector: StateSelector = (state) => state as unknown as T, equalityFn?: EqualityChecker, ) { - return useStore()(selector, equalityFn) + return useStore()(selector, equalityFn as any) } /** diff --git a/packages/fiber/src/core/index.tsx b/packages/fiber/src/core/index.tsx index a75768931a..4d49244e57 100644 --- a/packages/fiber/src/core/index.tsx +++ b/packages/fiber/src/core/index.tsx @@ -1,12 +1,13 @@ import * as THREE from 'three' import * as React from 'react' import { ConcurrentRoot } from 'react-reconciler/constants' -import create, { UseBoundStore } from 'zustand' +import create, { StoreApi, UseBoundStore } from 'zustand' import * as ReactThreeFiber from '../three-types' import { Renderer, createStore, + three, isRenderer, context, RootState, @@ -99,7 +100,7 @@ export type RenderProps = { manual?: boolean } /** An R3F event manager to manage elements' pointer events */ - events?: (store: UseBoundStore) => EventManager + events?: (store: UseBoundStore>) => EventManager /** Callback after the canvas has rendered (but not yet committed) */ onCreated?: (state: RootState) => void /** Response for pointer clicks that have missed any target */ @@ -121,7 +122,7 @@ const createRendererInstance = (gl: GLProps, canvas: TCa export type ReconcilerRoot = { configure: (config?: RenderProps) => ReconcilerRoot - render: (element: React.ReactNode) => UseBoundStore + render: (element: React.ReactNode) => UseBoundStore> unmount: () => void } @@ -147,7 +148,10 @@ function computeInitialSize(canvas: Canvas, defaultSize?: Size): Size { return { width: 0, height: 0, top: 0, left: 0 } } -function createRoot(canvas: TCanvas): ReconcilerRoot { +function createRoot( + canvas: TCanvas, + store?: UseBoundStore>, +): ReconcilerRoot { // Check against mistaken use of createRoot const prevRoot = roots.get(canvas) const prevFiber = prevRoot?.fiber @@ -166,12 +170,13 @@ function createRoot(canvas: TCanvas): ReconcilerRoot void) | undefined @@ -199,7 +204,7 @@ function createRoot(canvas: TCanvas): ReconcilerRoot(canvas: TCanvas): ReconcilerRoot { - const state = store.getState() + const state = actualStore.getState() if (state.frameloop === 'never') return advance(timestamp, true, state, frame) } // Toggle render switching on session const handleSessionChange = () => { - const state = store.getState() + const state = actualStore.getState() state.gl.xr.enabled = state.gl.xr.isPresenting state.gl.xr.setAnimationLoop(state.gl.xr.isPresenting ? handleXRFrame : null) @@ -272,12 +277,12 @@ function createRoot(canvas: TCanvas): ReconcilerRoot(canvas: TCanvas): ReconcilerRoot(canvas: TCanvas): ReconcilerRoot, + , fiber, null, () => undefined, ) - return store + return actualStore }, unmount() { unmountComponentAtNode(canvas) @@ -385,7 +390,7 @@ function render( children: React.ReactNode, canvas: TCanvas, config: RenderProps, -): UseBoundStore { +): UseBoundStore> { console.warn('R3F.render is no longer supported in React 18. Use createRoot instead!') const root = createRoot(canvas) root.configure(config) @@ -399,7 +404,7 @@ function Provider({ rootElement, }: { onCreated?: (state: RootState) => void - store: UseBoundStore + store: UseBoundStore> children: React.ReactNode rootElement: TCanvas }) { @@ -414,6 +419,7 @@ function Provider({ if (!store.getState().events.connected) state.events.connect?.(rootElement) // eslint-disable-next-line react-hooks/exhaustive-deps }, []) + return {children} } @@ -603,6 +609,8 @@ export { addTail, flushGlobalEffects, getRootState, + createStore, + three, act, buildGraph, roots as _roots, diff --git a/packages/fiber/src/core/renderer.ts b/packages/fiber/src/core/renderer.ts index ccd98265e0..625af3f518 100644 --- a/packages/fiber/src/core/renderer.ts +++ b/packages/fiber/src/core/renderer.ts @@ -1,5 +1,5 @@ import * as THREE from 'three' -import { UseBoundStore } from 'zustand' +import { StoreApi, UseBoundStore } from 'zustand' import Reconciler from 'react-reconciler' import { unstable_IdlePriority as idlePriority, unstable_scheduleCallback as scheduleCallback } from 'scheduler' import { DefaultEventPriority } from 'react-reconciler/constants' @@ -18,11 +18,11 @@ import { import { RootState } from './store' import { EventHandlers, removeInteractivity } from './events' -export type Root = { fiber: Reconciler.FiberRoot; store: UseBoundStore } +export type Root = { fiber: Reconciler.FiberRoot; store: UseBoundStore> } export type LocalState = { type: string - root: UseBoundStore + root: UseBoundStore> // objects and parent are used when children are added with `attach` instead of being added to the Object3D scene graph objects: Instance[] parent: Instance | null @@ -41,7 +41,7 @@ export type AttachType = string | AttachFnType interface HostConfig { type: string props: InstanceProps - container: UseBoundStore + container: UseBoundStore> instance: Instance textInstance: void suspenseInstance: Instance @@ -89,7 +89,7 @@ function createRenderer(_roots: Map, _getEventPriority?: function createInstance( type: string, { args = [], attach, ...props }: InstanceProps, - root: UseBoundStore, + root: UseBoundStore>, ) { let name = `${type[0].toUpperCase()}${type.slice(1)}` let instance: Instance diff --git a/packages/fiber/src/core/store.ts b/packages/fiber/src/core/store.ts index 6f809fb274..21b1c9d89f 100644 --- a/packages/fiber/src/core/store.ts +++ b/packages/fiber/src/core/store.ts @@ -1,6 +1,6 @@ import * as THREE from 'three' import * as React from 'react' -import create, { GetState, SetState, StoreApi, UseBoundStore } from 'zustand' +import { create, StateCreator, StoreApi, StoreMutatorIdentifier, UseBoundStore } from 'zustand' import { DomEvent, EventManager, PointerCaptureTarget, ThreeEvent } from './events' import { _XRFrame, calculateDpr, Camera, isOrthographicCamera, updateCamera } from './utils' @@ -27,7 +27,7 @@ export interface Intersection extends THREE.Intersection { export type Subscription = { ref: React.MutableRefObject priority: number - store: UseBoundStore> + store: UseBoundStore> } export type Dpr = number | [min: number, max: number] @@ -84,15 +84,15 @@ export type InternalState = { subscribe: ( callback: React.MutableRefObject, priority: number, - store: UseBoundStore>, + store: UseBoundStore>, ) => () => void } export type RootState = { /** Set current state */ - set: SetState + set: StoreApi['setState'] /** Get current state */ - get: GetState + get: StoreApi['getState'] /** The instance of the renderer */ gl: THREE.WebGLRenderer /** Default camera */ @@ -156,186 +156,25 @@ export type RootState = { setFrameloop: (frameloop?: 'always' | 'demand' | 'never') => void /** When the canvas was clicked but nothing was hit */ onPointerMissed?: (event: MouseEvent) => void - /** If this state model is layered (via createPortal) then this contains the previous layer */ - previousRoot?: UseBoundStore> + /** If this state model is layerd (via createPortal) then this contains the previous layer */ + previousRoot?: UseBoundStore> /** Internals */ internal: InternalState } -const context = React.createContext>(null!) +const context = React.createContext>>(null!) -const createStore = ( +const subscribeInvalidateChanges = ( + state: RootState, + api: StoreApi, invalidate: (state?: RootState, frames?: number) => void, - advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState, frame?: _XRFrame) => void, -): UseBoundStore => { - const rootState = create((set, get) => { - const position = new THREE.Vector3() - const defaultTarget = new THREE.Vector3() - const tempTarget = new THREE.Vector3() - function getCurrentViewport( - camera: Camera = get().camera, - target: THREE.Vector3 | Parameters = defaultTarget, - size: Size = get().size, - ): Omit { - const { width, height, top, left } = size - const aspect = width / height - if (target instanceof THREE.Vector3) tempTarget.copy(target) - else tempTarget.set(...target) - const distance = camera.getWorldPosition(position).distanceTo(tempTarget) - if (isOrthographicCamera(camera)) { - return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect } - } else { - const fov = (camera.fov * Math.PI) / 180 // convert vertical fov to radians - const h = 2 * Math.tan(fov / 2) * distance // visible height - const w = h * (width / height) - return { width: w, height: h, top, left, factor: width / w, distance, aspect } - } - } - - let performanceTimeout: ReturnType | undefined = undefined - const setPerformanceCurrent = (current: number) => - set((state) => ({ performance: { ...state.performance, current } })) - - const pointer = new THREE.Vector2() - - const rootState: RootState = { - set, - get, - - // Mock objects that have to be configured - gl: null as unknown as THREE.WebGLRenderer, - camera: null as unknown as Camera, - raycaster: null as unknown as THREE.Raycaster, - events: { priority: 1, enabled: true, connected: false }, - xr: null as unknown as { connect: () => void; disconnect: () => void }, - scene: null as unknown as THREE.Scene, - - invalidate: (frames = 1) => invalidate(get(), frames), - advance: (timestamp: number, runGlobalEffects?: boolean) => advance(timestamp, runGlobalEffects, get()), - - legacy: false, - linear: false, - flat: false, - - controls: null, - clock: new THREE.Clock(), - pointer, - mouse: pointer, - - frameloop: 'always', - onPointerMissed: undefined, - - performance: { - current: 1, - min: 0.5, - max: 1, - debounce: 200, - regress: () => { - const state = get() - // Clear timeout - if (performanceTimeout) clearTimeout(performanceTimeout) - // Set lower bound performance - if (state.performance.current !== state.performance.min) setPerformanceCurrent(state.performance.min) - // Go back to upper bound performance after a while unless something regresses meanwhile - performanceTimeout = setTimeout( - () => setPerformanceCurrent(get().performance.max), - state.performance.debounce, - ) - }, - }, - - size: { width: 0, height: 0, top: 0, left: 0, updateStyle: false }, - viewport: { - initialDpr: 0, - dpr: 0, - width: 0, - height: 0, - top: 0, - left: 0, - aspect: 0, - distance: 0, - factor: 0, - getCurrentViewport, - }, - - setEvents: (events: Partial>) => - set((state) => ({ ...state, events: { ...state.events, ...events } })), - setSize: (width: number, height: number, updateStyle?: boolean, top?: number, left?: number) => { - const camera = get().camera - const size = { width, height, top: top || 0, left: left || 0, updateStyle } - set((state) => ({ size, viewport: { ...state.viewport, ...getCurrentViewport(camera, defaultTarget, size) } })) - }, - setDpr: (dpr: Dpr) => - set((state) => { - const resolved = calculateDpr(dpr) - return { viewport: { ...state.viewport, dpr: resolved, initialDpr: state.viewport.initialDpr || resolved } } - }), - setFrameloop: (frameloop: 'always' | 'demand' | 'never' = 'always') => { - const clock = get().clock - - // if frameloop === "never" clock.elapsedTime is updated using advance(timestamp) - clock.stop() - clock.elapsedTime = 0 - - if (frameloop !== 'never') { - clock.start() - clock.elapsedTime = 0 - } - set(() => ({ frameloop })) - }, - - previousRoot: undefined, - internal: { - active: false, - priority: 0, - frames: 0, - lastEvent: React.createRef(), - - interaction: [], - hovered: new Map>(), - subscribers: [], - initialClick: [0, 0], - initialHits: [], - capturedMap: new Map(), - - subscribe: ( - ref: React.MutableRefObject, - priority: number, - store: UseBoundStore>, - ) => { - const internal = get().internal - // If this subscription was given a priority, it takes rendering into its own hands - // For that reason we switch off automatic rendering and increase the manual flag - // As long as this flag is positive there can be no internal rendering at all - // because there could be multiple render subscriptions - internal.priority = internal.priority + (priority > 0 ? 1 : 0) - internal.subscribers.push({ ref, priority, store }) - // Register subscriber and sort layers from lowest to highest, meaning, - // highest priority renders last (on top of the other frames) - internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority) - return () => { - const internal = get().internal - if (internal?.subscribers) { - // Decrease manual flag if this subscription had a priority - internal.priority = internal.priority - (priority > 0 ? 1 : 0) - // Remove subscriber from list - internal.subscribers = internal.subscribers.filter((s) => s.ref !== ref) - } - } - }, - }, - } - - return rootState - }) - - const state = rootState.getState() - +) => { let oldSize = state.size let oldDpr = state.viewport.dpr let oldCamera = state.camera - rootState.subscribe(() => { - const { camera, size, viewport, gl, set } = rootState.getState() + + api.subscribe(() => { + const { camera, size, viewport, gl, set } = api.getState() // Resize camera and renderer on changes to size and pixelratio if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) { @@ -359,8 +198,189 @@ const createStore = ( }) // Invalidate on any change - rootState.subscribe((state) => invalidate(state)) + api.subscribe((state) => invalidate(state)) +} +type Three = < + Mps extends [StoreMutatorIdentifier, unknown][] = [], + Mcs extends [StoreMutatorIdentifier, unknown][] = [], +>( + invalidate: (state?: RootState, frames?: number) => void, + advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState, frame?: _XRFrame) => void, +) => StateCreator + +type ThreeImpl = ( + invalidate: (state?: RootState, frames?: number) => void, + advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState, frame?: _XRFrame) => void, +) => StateCreator + +const threeImpl: ThreeImpl = (invalidate, advance) => (set, get, api) => { + const position = new THREE.Vector3() + const defaultTarget = new THREE.Vector3() + const tempTarget = new THREE.Vector3() + function getCurrentViewport( + camera: Camera = get().camera, + target: THREE.Vector3 | Parameters = defaultTarget, + size: Size = get().size, + ): Omit { + const { width, height, top, left } = size + const aspect = width / height + if (target instanceof THREE.Vector3) tempTarget.copy(target) + else tempTarget.set(...target) + const distance = camera.getWorldPosition(position).distanceTo(tempTarget) + if (isOrthographicCamera(camera)) { + return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect } + } else { + const fov = (camera.fov * Math.PI) / 180 // convert vertical fov to radians + const h = 2 * Math.tan(fov / 2) * distance // visible height + const w = h * (width / height) + return { width: w, height: h, top, left, factor: width / w, distance, aspect } + } + } + + let performanceTimeout: ReturnType | undefined = undefined + const setPerformanceCurrent = (current: number) => + set((state) => ({ performance: { ...state.performance, current } })) + + const pointer = new THREE.Vector2() + + const rootState: RootState = { + set, + get, + + // Mock objects that have to be configured + gl: null as unknown as THREE.WebGLRenderer, + camera: null as unknown as Camera, + raycaster: null as unknown as THREE.Raycaster, + events: { priority: 1, enabled: true, connected: false }, + xr: null as unknown as { connect: () => void; disconnect: () => void }, + scene: null as unknown as THREE.Scene, + + invalidate: (frames = 1) => invalidate(get(), frames), + advance: (timestamp: number, runGlobalEffects?: boolean) => advance(timestamp, runGlobalEffects, get()), + + legacy: false, + linear: false, + flat: false, + + controls: null, + clock: new THREE.Clock(), + pointer, + mouse: pointer, + + frameloop: 'always', + onPointerMissed: undefined, + + performance: { + current: 1, + min: 0.5, + max: 1, + debounce: 200, + regress: () => { + const state = get() + // Clear timeout + if (performanceTimeout) clearTimeout(performanceTimeout) + // Set lower bound performance + if (state.performance.current !== state.performance.min) setPerformanceCurrent(state.performance.min) + // Go back to upper bound performance after a while unless something regresses meanwhile + performanceTimeout = setTimeout(() => setPerformanceCurrent(get().performance.max), state.performance.debounce) + }, + }, + + size: { width: 0, height: 0, top: 0, left: 0, updateStyle: false }, + viewport: { + initialDpr: 0, + dpr: 0, + width: 0, + height: 0, + top: 0, + left: 0, + aspect: 0, + distance: 0, + factor: 0, + getCurrentViewport, + }, + + setEvents: (events: Partial>) => + set((state) => ({ ...state, events: { ...state.events, ...events } })), + setSize: (width: number, height: number, updateStyle?: boolean, top?: number, left?: number) => { + const camera = get().camera + const size = { width, height, top: top || 0, left: left || 0, updateStyle } + set((state) => ({ size, viewport: { ...state.viewport, ...getCurrentViewport(camera, defaultTarget, size) } })) + }, + setDpr: (dpr: Dpr) => + set((state) => { + const resolved = calculateDpr(dpr) + return { viewport: { ...state.viewport, dpr: resolved, initialDpr: state.viewport.initialDpr || resolved } } + }), + setFrameloop: (frameloop: 'always' | 'demand' | 'never' = 'always') => { + const clock = get().clock + + // if frameloop === "never" clock.elapsedTime is updated using advance(timestamp) + clock.stop() + clock.elapsedTime = 0 + + if (frameloop !== 'never') { + clock.start() + clock.elapsedTime = 0 + } + set(() => ({ frameloop })) + }, + + previousRoot: undefined, + internal: { + active: false, + priority: 0, + frames: 0, + lastEvent: React.createRef(), + + interaction: [], + hovered: new Map>(), + subscribers: [], + initialClick: [0, 0], + initialHits: [], + capturedMap: new Map(), + + subscribe: ( + ref: React.MutableRefObject, + priority: number, + store: UseBoundStore>, + ) => { + const internal = get().internal + // If this subscription was given a priority, it takes rendering into its own hands + // For that reason we switch off automatic rendering and increase the manual flag + // As long as this flag is positive there can be no internal rendering at all + // because there could be multiple render subscriptions + internal.priority = internal.priority + (priority > 0 ? 1 : 0) + internal.subscribers.push({ ref, priority, store }) + // Register subscriber and sort layers from lowest to highest, meaning, + // highest priority renders last (on top of the other frames) + internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority) + return () => { + const internal = get().internal + if (internal?.subscribers) { + // Decrease manual flag if this subscription had a priority + internal.priority = internal.priority - (priority > 0 ? 1 : 0) + // Remove subscriber from list + internal.subscribers = internal.subscribers.filter((s) => s.ref !== ref) + } + } + }, + }, + } + + subscribeInvalidateChanges(rootState, api, invalidate) + + return rootState +} + +export const three = threeImpl as unknown as Three + +const createStore = ( + invalidate: (state?: RootState, frames?: number) => void, + advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState, frame?: _XRFrame) => void, +): UseBoundStore> => { + const rootState = create(threeImpl(invalidate, advance)) // Return root state return rootState } diff --git a/packages/fiber/src/core/utils.ts b/packages/fiber/src/core/utils.ts index 7089f3e583..b1e44c9d80 100644 --- a/packages/fiber/src/core/utils.ts +++ b/packages/fiber/src/core/utils.ts @@ -1,7 +1,7 @@ /// import * as THREE from 'three' import * as React from 'react' -import { UseBoundStore } from 'zustand' +import { StoreApi, UseBoundStore } from 'zustand' import { EventHandlers } from './events' import { AttachType, catalogue, Instance, InstanceProps, LocalState } from './renderer' import { Dpr, Renderer, RootState, Size } from './store' @@ -196,7 +196,7 @@ export function prepare(object: T, state?: Partial, + root: null as unknown as UseBoundStore>, previousAttach: null, memoizedProps: {}, eventCount: 0, diff --git a/packages/fiber/src/native/events.ts b/packages/fiber/src/native/events.ts index 0e4ef1bb36..8ec8537859 100644 --- a/packages/fiber/src/native/events.ts +++ b/packages/fiber/src/native/events.ts @@ -1,10 +1,10 @@ -import { UseBoundStore } from 'zustand' +import { StoreApi, UseBoundStore } from 'zustand' import { RootState } from '../core/store' import { createEvents, DomEvent, EventManager, Events } from '../core/events' import { type GestureResponderEvent, PanResponder } from 'react-native' /** Default R3F event manager for react-native */ -export function createTouchEvents(store: UseBoundStore): EventManager { +export function createTouchEvents(store: UseBoundStore>): EventManager { const { handlePointer } = createEvents(store) const handleTouch = (event: GestureResponderEvent, name: string): true => { diff --git a/packages/fiber/src/web/Canvas.tsx b/packages/fiber/src/web/Canvas.tsx index a25584e357..020488bfec 100644 --- a/packages/fiber/src/web/Canvas.tsx +++ b/packages/fiber/src/web/Canvas.tsx @@ -7,6 +7,8 @@ import { isRef, SetBlock, Block, ErrorBoundary, useMutableCallback, useIsomorphi import { ReconcilerRoot, extend, createRoot, unmountComponentAtNode, RenderProps } from '../core' import { createPointerEvents } from './events' import { DomEvent } from '../core/events' +import { StoreApi, UseBoundStore } from 'zustand' +import { RootState } from '../native' export interface CanvasProps extends Omit, 'size'>, @@ -23,6 +25,8 @@ export interface CanvasProps eventSource?: HTMLElement | React.MutableRefObject /** The event prefix that is cast into canvas pointer x/y events, default: "offset" */ eventPrefix?: 'offset' | 'client' | 'page' | 'layer' | 'screen' + /** Custom store for passing state to the canvas */ + store?: UseBoundStore> } export interface Props extends CanvasProps {} @@ -48,6 +52,7 @@ const CanvasImpl = /*#__PURE__*/ React.forwardRef(func raycaster, camera, scene, + store, onPointerMissed, onCreated, ...props @@ -80,7 +85,7 @@ const CanvasImpl = /*#__PURE__*/ React.forwardRef(func useIsomorphicLayoutEffect(() => { const canvas = canvasRef.current if (containerRect.width > 0 && containerRect.height > 0 && canvas) { - if (!root.current) root.current = createRoot(canvas) + if (!root.current) root.current = createRoot(canvas, store) root.current.configure({ gl, events, diff --git a/packages/fiber/src/web/events.ts b/packages/fiber/src/web/events.ts index 0bb836c4fc..6eb680c4d6 100644 --- a/packages/fiber/src/web/events.ts +++ b/packages/fiber/src/web/events.ts @@ -1,4 +1,4 @@ -import { UseBoundStore } from 'zustand' +import { StoreApi, UseBoundStore } from 'zustand' import { RootState } from '../core/store' import { EventManager, Events, createEvents, DomEvent } from '../core/events' @@ -16,7 +16,7 @@ const DOM_EVENTS = { } as const /** Default R3F event manager for web */ -export function createPointerEvents(store: UseBoundStore): EventManager { +export function createPointerEvents(store: UseBoundStore>): EventManager { const { handlePointer } = createEvents(store) return { diff --git a/packages/fiber/tests/core/renderer.test.tsx b/packages/fiber/tests/core/renderer.test.tsx index 4b729f43b0..7a60d6bc6d 100644 --- a/packages/fiber/tests/core/renderer.test.tsx +++ b/packages/fiber/tests/core/renderer.test.tsx @@ -12,7 +12,7 @@ import { useThree, createPortal, } from '../../src/index' -import { UseBoundStore } from 'zustand' +import { StoreApi, UseBoundStore } from 'zustand' import { privateKeys, RootState } from '../../src/core/store' import { Instance } from '../../src/core/renderer' @@ -571,7 +571,7 @@ describe('renderer', () => { }) it('should handle an performance changing functions', async () => { - let state: UseBoundStore = null! + let state: UseBoundStore> = null! await act(async () => { state = root.configure({ dpr: [1, 2], performance: { min: 0.2 } }).render() }) @@ -605,7 +605,7 @@ describe('renderer', () => { }) it('should set PCFSoftShadowMap as the default shadow map', async () => { - let state: UseBoundStore = null! + let state: UseBoundStore> = null! await act(async () => { state = root.configure({ shadows: true }).render() }) @@ -614,7 +614,7 @@ describe('renderer', () => { }) it('should set tonemapping to ACESFilmicToneMapping and outputEncoding to sRGBEncoding if linear is false', async () => { - let state: UseBoundStore = null! + let state: UseBoundStore> = null! await act(async () => { state = root.configure({ linear: false }).render() }) diff --git a/packages/test-renderer/src/types/internal.ts b/packages/test-renderer/src/types/internal.ts index d4b54d936b..5561890bfe 100644 --- a/packages/test-renderer/src/types/internal.ts +++ b/packages/test-renderer/src/types/internal.ts @@ -1,9 +1,9 @@ import * as THREE from 'three' -import { UseBoundStore } from 'zustand' +import { UseBoundStore, StoreApi } from 'zustand' import type { BaseInstance, LocalState, RootState } from '@react-three/fiber' -export type MockUseStoreState = UseBoundStore +export type MockUseStoreState = UseBoundStore> export interface MockInstance extends Omit { __r3f: Omit & { diff --git a/yarn.lock b/yarn.lock index 78c25d47de..c9998f8cc5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,7 +24,15 @@ dependencies: "@babel/highlight" "^7.18.6" -"@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": +"@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.4.tgz#03ae5af150be94392cb5c7ccd97db5a19a5da6aa" + integrity sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + +"@babel/code-frame@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== @@ -37,6 +45,11 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.10.tgz#9d92fa81b87542fff50e848ed585b4212c1d34ec" integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg== +"@babel/compat-data@^7.22.9": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.3.tgz#3febd552541e62b5e883a25eb3effd7c7379db11" + integrity sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ== + "@babel/compat-data@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" @@ -63,7 +76,7 @@ json5 "^2.1.2" semver "^6.3.0" -"@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.14.0", "@babel/core@^7.14.8", "@babel/core@^7.7.2", "@babel/core@^7.7.7", "@babel/core@^7.8.0": +"@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.14.0", "@babel/core@^7.7.2", "@babel/core@^7.7.7", "@babel/core@^7.8.0": version "7.20.12" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.12.tgz#7930db57443c6714ad216953d1356dac0eb8496d" integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== @@ -84,6 +97,27 @@ json5 "^2.2.2" semver "^6.3.0" +"@babel/core@^7.14.8": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.3.tgz#5ec09c8803b91f51cc887dedc2654a35852849c9" + integrity sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.3" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.2" + "@babel/parser" "^7.23.3" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.3" + "@babel/types" "^7.23.3" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + "@babel/core@^7.23.5": version "7.23.7" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.7.tgz#4d8016e06a14b5f92530a13ed0561730b5c6483f" @@ -114,6 +148,16 @@ "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" +"@babel/generator@^7.23.3", "@babel/generator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.4.tgz#4a41377d8566ec18f807f42962a7f3551de83d1c" + integrity sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ== + dependencies: + "@babel/types" "^7.23.4" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + "@babel/generator@^7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" @@ -150,6 +194,17 @@ lru-cache "^5.1.1" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" + integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.15" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + "@babel/helper-compilation-targets@^7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" @@ -386,6 +441,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== +"@babel/helper-validator-option@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" + integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== + "@babel/helper-validator-option@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" @@ -410,6 +470,15 @@ "@babel/traverse" "^7.20.7" "@babel/types" "^7.20.7" +"@babel/helpers@^7.23.2": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.4.tgz#7d2cfb969aa43222032193accd7329851facf3c1" + integrity sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.4" + "@babel/types" "^7.23.4" + "@babel/helpers@^7.23.7": version "7.23.8" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.8.tgz#fc6b2d65b16847fd50adddbd4232c76378959e34" @@ -442,7 +511,12 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b" integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg== -"@babel/parser@^7.22.15", "@babel/parser@^7.23.6": +"@babel/parser@^7.22.15", "@babel/parser@^7.23.3", "@babel/parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.4.tgz#409fbe690c333bb70187e2de4021e1e47a026661" + integrity sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ== + +"@babel/parser@^7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b" integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== @@ -953,28 +1027,28 @@ dependencies: "@babel/plugin-transform-react-jsx" "^7.16.7" -"@babel/plugin-transform-react-jsx-self@^7.0.0", "@babel/plugin-transform-react-jsx-self@^7.14.5": +"@babel/plugin-transform-react-jsx-self@^7.0.0": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.16.7.tgz#f432ad0cba14c4a1faf44f0076c69e42a4d4479e" integrity sha512-oe5VuWs7J9ilH3BCCApGoYjHoSO48vkjX2CbA5bFVhIuO2HKxA3vyF7rleA4o6/4rTDbk6r8hBW7Ul8E+UZrpA== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-react-jsx-self@^7.23.3": +"@babel/plugin-transform-react-jsx-self@^7.14.5", "@babel/plugin-transform-react-jsx-self@^7.23.3": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz#ed3e7dadde046cce761a8e3cf003a13d1a7972d9" integrity sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-react-jsx-source@^7.0.0", "@babel/plugin-transform-react-jsx-source@^7.14.5": +"@babel/plugin-transform-react-jsx-source@^7.0.0": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.7.tgz#1879c3f23629d287cc6186a6c683154509ec70c0" integrity sha512-rONFiQz9vgbsnaMtQlZCjIRwhJvlrPET8TabIUK2hzlXw9B9s2Ieaxte1SCOOXMbWRHodbKixNf3BLcWVOQ8Bw== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-react-jsx-source@^7.23.3": +"@babel/plugin-transform-react-jsx-source@^7.14.5", "@babel/plugin-transform-react-jsx-source@^7.23.3": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz#03527006bdc8775247a78643c51d4e715fe39a3e" integrity sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g== @@ -1259,6 +1333,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.23.3", "@babel/traverse@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.4.tgz#c2790f7edf106d059a0098770fe70801417f3f85" + integrity sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg== + dependencies: + "@babel/code-frame" "^7.23.4" + "@babel/generator" "^7.23.4" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.4" + "@babel/types" "^7.23.4" + debug "^4.1.0" + globals "^11.1.0" + "@babel/traverse@^7.23.7": version "7.23.7" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.7.tgz#9a7bf285c928cb99b5ead19c3b1ce5b310c9c305" @@ -1284,7 +1374,16 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" -"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6": +"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.3", "@babel/types@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.4.tgz#7206a1810fc512a7f7f7d4dace4cb4c1c9dbfb8e" + integrity sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@babel/types@^7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd" integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg== @@ -2129,12 +2228,12 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== -"@jridgewell/resolve-uri@^3.1.0": +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": version "3.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== @@ -2171,9 +2270,9 @@ "@jridgewell/sourcemap-codec" "1.4.14" "@jridgewell/trace-mapping@^0.3.17": - version "0.3.21" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.21.tgz#5dc1df7b3dc4a6209e503a924e1ca56097a2bb15" - integrity sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g== + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== dependencies: "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" @@ -2762,9 +2861,9 @@ integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== "@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== "@types/aria-query@^4.2.0": version "4.2.2" @@ -2821,9 +2920,9 @@ integrity sha512-goh23EGr6CLV6aKPwN1p8kBD/7tT5V/bLpToSbarKrwVejqNrspVrv8DhliteYkkhZYrlq/fwKZRRUzH4XN88w== "@types/eslint@^8.4.10": - version "8.4.10" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.10.tgz#19731b9685c19ed1552da7052b6f668ed7eb64bb" - integrity sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw== + version "8.44.7" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.7.tgz#430b3cc96db70c81f405e6a08aebdb13869198f5" + integrity sha512-f5ORu2hcBbKei97U73mf+l9t4zTGl74IqZ0GQk4oVea/VS8tQZYkUveSYojk+frraAVYId0V2WC9O4PTNru2FQ== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -2851,9 +2950,9 @@ "@types/node" "*" "@types/hoist-non-react-statics@*": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" - integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + version "3.3.5" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494" + integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg== dependencies: "@types/react" "*" hoist-non-react-statics "^3.3.0" @@ -2892,7 +2991,12 @@ expect "^29.0.0" pretty-format "^29.0.0" -"@types/json-schema@*", "@types/json-schema@^7.0.9": +"@types/json-schema@*": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== @@ -2903,9 +3007,9 @@ integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/lodash@^4.14.191": - version "4.14.191" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa" - integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== + version "4.14.202" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" + integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== "@types/minimatch@^3.0.3": version "3.0.5" @@ -3269,20 +3373,25 @@ acorn-walk@^7.1.1: integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + version "8.3.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f" + integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA== acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.8.0: +acorn@^8.2.4, acorn@^8.5.0, acorn@^8.8.0: version "8.8.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== +acorn@^8.4.1: + version "8.11.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -3836,6 +3945,16 @@ browserslist@^4.20.2, browserslist@^4.21.3: node-releases "^2.0.6" update-browserslist-db "^1.0.9" +browserslist@^4.21.9: + version "4.22.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" + integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== + dependencies: + caniuse-lite "^1.0.30001541" + electron-to-chromium "^1.4.535" + node-releases "^2.0.13" + update-browserslist-db "^1.0.13" + browserslist@^4.22.2: version "4.22.2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" @@ -3977,10 +4096,10 @@ camera-controls@^2.4.2: resolved "https://registry.yarnpkg.com/camera-controls/-/camera-controls-2.7.3.tgz#99e0449f68d203bf5f98f6c4ac0021c10b5c13a8" integrity sha512-L4mxjBd3u8qiOLozdWrH2P8ZybSsDXBF7iyNyqNEFJhPUkovmuARWR8JTc1B/qlclOIg6FvZZA/0uAZMMim0mw== -caniuse-lite@^1.0.30001400: - version "1.0.30001444" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001444.tgz#c0a530776eb44d933b493de1d05346f2527b30fc" - integrity sha512-ecER9xgJQVMqcrxThKptsW0pPxSae8R2RB87LNa+ivW9ppNWRHEplXcDzkCOP4LYWGj8hunXLqaiC41iBATNyg== +caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001541: + version "1.0.30001564" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001564.tgz" + integrity sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg== caniuse-lite@^1.0.30001565: version "1.0.30001576" @@ -4653,6 +4772,11 @@ electron-to-chromium@^1.4.251: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== +electron-to-chromium@^1.4.535: + version "1.4.592" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.592.tgz#1ffd49ba3da3da3077ea20014b066c910d50c913" + integrity sha512-D3NOkROIlF+d5ixnz7pAf3Lu/AuWpd6AYgI9O67GQXMXTcCP1gJQRotOq35eQy5Sb4hez33XH1YdTtILA7Udww== + electron-to-chromium@^1.4.601: version "1.4.629" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.629.tgz#9cbffe1b08a5627b6a25118360f7fd3965416caf" @@ -8086,6 +8210,11 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== + node-releases@^2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" @@ -10866,11 +10995,18 @@ zstddec@^0.0.2: resolved "https://registry.yarnpkg.com/zstddec/-/zstddec-0.0.2.tgz#57e2f28dd1ff56b750e07d158a43f0611ad9eeb4" integrity sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA== -zustand@^3.5.13, zustand@^3.7.1: +zustand@^3.5.13: version "3.7.2" resolved "https://registry.yarnpkg.com/zustand/-/zustand-3.7.2.tgz#7b44c4f4a5bfd7a8296a3957b13e1c346f42514d" integrity sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA== +zustand@^4.4.1: + version "4.4.6" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.6.tgz#03c78e3e2686c47095c93714c0c600b72a6512bd" + integrity sha512-Rb16eW55gqL4W2XZpJh0fnrATxYEG3Apl2gfHTyDSE965x/zxslTikpNch0JgNjJA9zK6gEFW8Fl6d1rTZaqgg== + dependencies: + use-sync-external-store "1.2.0" + zustand@^4.4.7: version "4.4.7" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.7.tgz#355406be6b11ab335f59a66d2cf9815e8f24038c"