@react-three/fiber 7.0.6 → 7.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @react-three/fiber
2
2
 
3
+ ## 7.0.7
4
+
5
+ ### Patch Changes
6
+
7
+ - 0375896: Simplify useframe, support instanced event cancelation, silence disposal
8
+
3
9
  ## 7.0.6
4
10
 
5
11
  ### Patch Changes
@@ -17,6 +17,7 @@ export declare type ObjectMap = {
17
17
  [name: string]: THREE.Material;
18
18
  };
19
19
  };
20
+ export declare function useStore(): import("zustand").UseStore<RootState>;
20
21
  export declare function useThree<T = RootState>(selector?: StateSelector<RootState, T>, equalityFn?: EqualityChecker<T>): T;
21
22
  export declare function useFrame(callback: RenderCallback, renderPriority?: number): null;
22
23
  export declare function useGraph(object: THREE.Object3D): ObjectMap;
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import * as THREE from 'three';
3
2
  import { EventHandlers } from './core/events';
4
3
  export declare type NonFunctionKeys<T> = {
@@ -13,7 +13,7 @@ declare const modes: readonly ["legacy", "blocking", "concurrent"];
13
13
  declare const invalidate: (state?: RootState | undefined) => void, advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState | undefined) => void;
14
14
  declare const reconciler: import("react-reconciler").Reconciler<unknown, unknown, unknown, unknown, unknown>, applyProps: (instance: import("../core/renderer").Instance, newProps: import("../core/renderer").InstanceProps, oldProps?: import("../core/renderer").InstanceProps, accumulative?: boolean) => void;
15
15
  export declare type RenderProps<TCanvas extends Element> = Omit<StoreProps, 'gl' | 'events' | 'size'> & {
16
- gl?: THREE.WebGLRenderer | THREE.WebGLRendererParameters;
16
+ gl?: THREE.WebGLRenderer | Partial<THREE.WebGLRendererParameters>;
17
17
  events?: (store: UseStore<RootState>) => EventManager<TCanvas>;
18
18
  size?: Size;
19
19
  mode?: typeof modes[number];
@@ -74,7 +74,7 @@ const is = {
74
74
  };
75
75
 
76
76
  function makeId(event) {
77
- return (event.eventObject || event.object).uuid + '/' + event.index;
77
+ return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
78
78
  }
79
79
 
80
80
  function removeInteractivity(store, object) {
@@ -306,7 +306,7 @@ function createEvents(store) {
306
306
  Array.from(internal.hovered.values()).forEach(hoveredObj => {
307
307
  // When no objects were hit or the the hovered object wasn't found underneath the cursor
308
308
  // we call onPointerOut and delete the object from the hovered-elements map
309
- if (!hits.length || !hits.find(hit => hit.object === hoveredObj.object && hit.index === hoveredObj.index)) {
309
+ if (!hits.length || !hits.find(hit => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId)) {
310
310
  const eventObject = hoveredObj.eventObject;
311
311
  const handlers = eventObject.__r3f.handlers;
312
312
  internal.hovered.delete(makeId(hoveredObj));
@@ -844,7 +844,7 @@ function createRenderer(roots) {
844
844
  // Never dispose of primitives because their state may be kept outside of React!
845
845
  // In order for an object to be able to dispose it has to have
846
846
  // - a dispose method,
847
- // - it cannot be an <instance object={...} />
847
+ // - it cannot be a <primitive object={...} />
848
848
  // - it cannot be a THREE.Scene, because three has broken it's own api
849
849
  //
850
850
  // Since disposal is recursive, we can check the optional dispose arg, which will be undefined
@@ -873,7 +873,13 @@ function createRenderer(roots) {
873
873
 
874
874
 
875
875
  if (shouldDispose && child.dispose && child.type !== 'Scene') {
876
- scheduler.unstable_runWithPriority(scheduler.unstable_IdlePriority, () => child.dispose());
876
+ scheduler.unstable_runWithPriority(scheduler.unstable_IdlePriority, () => {
877
+ try {
878
+ child.dispose();
879
+ } catch (e) {
880
+ /* ... */
881
+ }
882
+ });
877
883
  }
878
884
 
879
885
  invalidateInstance(parentInstance);
@@ -1256,8 +1262,8 @@ const createStore = (applyProps, invalidate, advance, props) => {
1256
1262
  internal: { ...internal,
1257
1263
  // If this subscription was given a priority, it takes rendering into its own hands
1258
1264
  // For that reason we switch off automatic rendering and increase the manual flag
1259
- // As long as this flag is positive (there could be multiple render subscription)
1260
- // ..there can be no internal rendering at all
1265
+ // As long as this flag is positive there can be no internal rendering at all
1266
+ // because there could be multiple render subscriptions
1261
1267
  priority: internal.priority + (priority > 0 ? 1 : 0),
1262
1268
  // Register subscriber and sort layers from lowest to highest, meaning,
1263
1269
  // highest priority renders last (on top of the other frames)
@@ -1577,23 +1583,21 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
1577
1583
  }, fallback));
1578
1584
  });
1579
1585
 
1586
+ function useStore() {
1587
+ const store = React__namespace.useContext(context);
1588
+ if (!store) throw `R3F hooks can only be used within the Canvas component!`;
1589
+ return store;
1590
+ }
1580
1591
  function useThree(selector = state => state, equalityFn) {
1581
- const useStore = React__namespace.useContext(context);
1582
- if (!useStore) throw `R3F hooks can only be used within the Canvas component!`;
1583
- return useStore(selector, equalityFn);
1592
+ return useStore()(selector, equalityFn);
1584
1593
  }
1585
1594
  function useFrame(callback, renderPriority = 0) {
1586
- const {
1587
- subscribe
1588
- } = React__namespace.useContext(context).getState().internal; // Update ref
1595
+ const subscribe = useStore().getState().internal.subscribe; // Update ref
1589
1596
 
1590
1597
  const ref = React__namespace.useRef(callback);
1591
- React__namespace.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe/unsub
1598
+ React__namespace.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe on mount, unsubscribe on unmount
1592
1599
 
1593
- React__namespace.useLayoutEffect(() => {
1594
- const unsubscribe = subscribe(ref, renderPriority);
1595
- return () => unsubscribe();
1596
- }, [renderPriority, subscribe]);
1600
+ React__namespace.useLayoutEffect(() => subscribe(ref, renderPriority), [renderPriority]);
1597
1601
  return null;
1598
1602
  }
1599
1603
 
@@ -1856,4 +1860,5 @@ exports.unmountComponentAtNode = unmountComponentAtNode;
1856
1860
  exports.useFrame = useFrame;
1857
1861
  exports.useGraph = useGraph;
1858
1862
  exports.useLoader = useLoader;
1863
+ exports.useStore = useStore;
1859
1864
  exports.useThree = useThree;
@@ -74,7 +74,7 @@ const is = {
74
74
  };
75
75
 
76
76
  function makeId(event) {
77
- return (event.eventObject || event.object).uuid + '/' + event.index;
77
+ return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
78
78
  }
79
79
 
80
80
  function removeInteractivity(store, object) {
@@ -306,7 +306,7 @@ function createEvents(store) {
306
306
  Array.from(internal.hovered.values()).forEach(hoveredObj => {
307
307
  // When no objects were hit or the the hovered object wasn't found underneath the cursor
308
308
  // we call onPointerOut and delete the object from the hovered-elements map
309
- if (!hits.length || !hits.find(hit => hit.object === hoveredObj.object && hit.index === hoveredObj.index)) {
309
+ if (!hits.length || !hits.find(hit => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId)) {
310
310
  const eventObject = hoveredObj.eventObject;
311
311
  const handlers = eventObject.__r3f.handlers;
312
312
  internal.hovered.delete(makeId(hoveredObj));
@@ -844,7 +844,7 @@ function createRenderer(roots) {
844
844
  // Never dispose of primitives because their state may be kept outside of React!
845
845
  // In order for an object to be able to dispose it has to have
846
846
  // - a dispose method,
847
- // - it cannot be an <instance object={...} />
847
+ // - it cannot be a <primitive object={...} />
848
848
  // - it cannot be a THREE.Scene, because three has broken it's own api
849
849
  //
850
850
  // Since disposal is recursive, we can check the optional dispose arg, which will be undefined
@@ -873,7 +873,13 @@ function createRenderer(roots) {
873
873
 
874
874
 
875
875
  if (shouldDispose && child.dispose && child.type !== 'Scene') {
876
- scheduler.unstable_runWithPriority(scheduler.unstable_IdlePriority, () => child.dispose());
876
+ scheduler.unstable_runWithPriority(scheduler.unstable_IdlePriority, () => {
877
+ try {
878
+ child.dispose();
879
+ } catch (e) {
880
+ /* ... */
881
+ }
882
+ });
877
883
  }
878
884
 
879
885
  invalidateInstance(parentInstance);
@@ -1256,8 +1262,8 @@ const createStore = (applyProps, invalidate, advance, props) => {
1256
1262
  internal: { ...internal,
1257
1263
  // If this subscription was given a priority, it takes rendering into its own hands
1258
1264
  // For that reason we switch off automatic rendering and increase the manual flag
1259
- // As long as this flag is positive (there could be multiple render subscription)
1260
- // ..there can be no internal rendering at all
1265
+ // As long as this flag is positive there can be no internal rendering at all
1266
+ // because there could be multiple render subscriptions
1261
1267
  priority: internal.priority + (priority > 0 ? 1 : 0),
1262
1268
  // Register subscriber and sort layers from lowest to highest, meaning,
1263
1269
  // highest priority renders last (on top of the other frames)
@@ -1577,23 +1583,21 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
1577
1583
  }, fallback));
1578
1584
  });
1579
1585
 
1586
+ function useStore() {
1587
+ const store = React__namespace.useContext(context);
1588
+ if (!store) throw `R3F hooks can only be used within the Canvas component!`;
1589
+ return store;
1590
+ }
1580
1591
  function useThree(selector = state => state, equalityFn) {
1581
- const useStore = React__namespace.useContext(context);
1582
- if (!useStore) throw `R3F hooks can only be used within the Canvas component!`;
1583
- return useStore(selector, equalityFn);
1592
+ return useStore()(selector, equalityFn);
1584
1593
  }
1585
1594
  function useFrame(callback, renderPriority = 0) {
1586
- const {
1587
- subscribe
1588
- } = React__namespace.useContext(context).getState().internal; // Update ref
1595
+ const subscribe = useStore().getState().internal.subscribe; // Update ref
1589
1596
 
1590
1597
  const ref = React__namespace.useRef(callback);
1591
- React__namespace.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe/unsub
1598
+ React__namespace.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe on mount, unsubscribe on unmount
1592
1599
 
1593
- React__namespace.useLayoutEffect(() => {
1594
- const unsubscribe = subscribe(ref, renderPriority);
1595
- return () => unsubscribe();
1596
- }, [renderPriority, subscribe]);
1600
+ React__namespace.useLayoutEffect(() => subscribe(ref, renderPriority), [renderPriority]);
1597
1601
  return null;
1598
1602
  }
1599
1603
 
@@ -1856,4 +1860,5 @@ exports.unmountComponentAtNode = unmountComponentAtNode;
1856
1860
  exports.useFrame = useFrame;
1857
1861
  exports.useGraph = useGraph;
1858
1862
  exports.useLoader = useLoader;
1863
+ exports.useStore = useStore;
1859
1864
  exports.useThree = useThree;
@@ -40,7 +40,7 @@ const is = {
40
40
  };
41
41
 
42
42
  function makeId(event) {
43
- return (event.eventObject || event.object).uuid + '/' + event.index;
43
+ return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
44
44
  }
45
45
 
46
46
  function removeInteractivity(store, object) {
@@ -272,7 +272,7 @@ function createEvents(store) {
272
272
  Array.from(internal.hovered.values()).forEach(hoveredObj => {
273
273
  // When no objects were hit or the the hovered object wasn't found underneath the cursor
274
274
  // we call onPointerOut and delete the object from the hovered-elements map
275
- if (!hits.length || !hits.find(hit => hit.object === hoveredObj.object && hit.index === hoveredObj.index)) {
275
+ if (!hits.length || !hits.find(hit => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId)) {
276
276
  const eventObject = hoveredObj.eventObject;
277
277
  const handlers = eventObject.__r3f.handlers;
278
278
  internal.hovered.delete(makeId(hoveredObj));
@@ -810,7 +810,7 @@ function createRenderer(roots) {
810
810
  // Never dispose of primitives because their state may be kept outside of React!
811
811
  // In order for an object to be able to dispose it has to have
812
812
  // - a dispose method,
813
- // - it cannot be an <instance object={...} />
813
+ // - it cannot be a <primitive object={...} />
814
814
  // - it cannot be a THREE.Scene, because three has broken it's own api
815
815
  //
816
816
  // Since disposal is recursive, we can check the optional dispose arg, which will be undefined
@@ -839,7 +839,13 @@ function createRenderer(roots) {
839
839
 
840
840
 
841
841
  if (shouldDispose && child.dispose && child.type !== 'Scene') {
842
- unstable_runWithPriority(unstable_IdlePriority, () => child.dispose());
842
+ unstable_runWithPriority(unstable_IdlePriority, () => {
843
+ try {
844
+ child.dispose();
845
+ } catch (e) {
846
+ /* ... */
847
+ }
848
+ });
843
849
  }
844
850
 
845
851
  invalidateInstance(parentInstance);
@@ -1222,8 +1228,8 @@ const createStore = (applyProps, invalidate, advance, props) => {
1222
1228
  internal: { ...internal,
1223
1229
  // If this subscription was given a priority, it takes rendering into its own hands
1224
1230
  // For that reason we switch off automatic rendering and increase the manual flag
1225
- // As long as this flag is positive (there could be multiple render subscription)
1226
- // ..there can be no internal rendering at all
1231
+ // As long as this flag is positive there can be no internal rendering at all
1232
+ // because there could be multiple render subscriptions
1227
1233
  priority: internal.priority + (priority > 0 ? 1 : 0),
1228
1234
  // Register subscriber and sort layers from lowest to highest, meaning,
1229
1235
  // highest priority renders last (on top of the other frames)
@@ -1543,23 +1549,21 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
1543
1549
  }, fallback));
1544
1550
  });
1545
1551
 
1552
+ function useStore() {
1553
+ const store = React.useContext(context);
1554
+ if (!store) throw `R3F hooks can only be used within the Canvas component!`;
1555
+ return store;
1556
+ }
1546
1557
  function useThree(selector = state => state, equalityFn) {
1547
- const useStore = React.useContext(context);
1548
- if (!useStore) throw `R3F hooks can only be used within the Canvas component!`;
1549
- return useStore(selector, equalityFn);
1558
+ return useStore()(selector, equalityFn);
1550
1559
  }
1551
1560
  function useFrame(callback, renderPriority = 0) {
1552
- const {
1553
- subscribe
1554
- } = React.useContext(context).getState().internal; // Update ref
1561
+ const subscribe = useStore().getState().internal.subscribe; // Update ref
1555
1562
 
1556
1563
  const ref = React.useRef(callback);
1557
- React.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe/unsub
1564
+ React.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe on mount, unsubscribe on unmount
1558
1565
 
1559
- React.useLayoutEffect(() => {
1560
- const unsubscribe = subscribe(ref, renderPriority);
1561
- return () => unsubscribe();
1562
- }, [renderPriority, subscribe]);
1566
+ React.useLayoutEffect(() => subscribe(ref, renderPriority), [renderPriority]);
1563
1567
  return null;
1564
1568
  }
1565
1569
 
@@ -1801,4 +1805,4 @@ reconciler.injectIntoDevTools({
1801
1805
  version: '17.0.2'
1802
1806
  });
1803
1807
 
1804
- export { Canvas, threeTypes as ReactThreeFiber, roots as _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, context, createPortal, dispose, createPointerEvents as events, extend, invalidate, reconciler, render, unmountComponentAtNode, useFrame, useGraph, useLoader, useThree };
1808
+ export { Canvas, threeTypes as ReactThreeFiber, roots as _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, context, createPortal, dispose, createPointerEvents as events, extend, invalidate, reconciler, render, unmountComponentAtNode, useFrame, useGraph, useLoader, useStore, useThree };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/fiber",
3
- "version": "7.0.6",
3
+ "version": "7.0.7",
4
4
  "description": "A React renderer for Threejs",
5
5
  "keywords": [
6
6
  "react",