@react-three/fiber 8.0.6 → 8.0.9

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,23 @@
1
1
  # @react-three/fiber
2
2
 
3
+ ## 8.0.9
4
+
5
+ ### Patch Changes
6
+
7
+ - 624df949: fix: canvas unmount race condition"
8
+
9
+ ## 8.0.8
10
+
11
+ ### Patch Changes
12
+
13
+ - 952a566: fix: react SSR
14
+
15
+ ## 8.0.7
16
+
17
+ ### Patch Changes
18
+
19
+ - f63806b: fix: react SSR
20
+
3
21
  ## 8.0.6
4
22
 
5
23
  ### Patch Changes
@@ -10,16 +10,12 @@ export declare type Extensions = (loader: THREE.Loader) => void;
10
10
  export declare type LoaderResult<T> = T extends any[] ? Loader<T[number]> : Loader<T>;
11
11
  export declare type ConditionalType<Child, Parent, Truthy, Falsy> = Child extends Parent ? Truthy : Falsy;
12
12
  export declare type BranchingReturn<T, Parent, Coerced> = ConditionalType<T, Parent, Coerced, T>;
13
- declare type noop = (...args: any[]) => any;
14
- declare type PickFunction<T extends noop> = (...args: Parameters<T>) => ReturnType<T>;
15
13
  export declare function useStore(): import("zustand").UseBoundStore<RootState, import("zustand").StoreApi<RootState>>;
16
14
  export declare function useThree<T = RootState>(selector?: StateSelector<RootState, T>, equalityFn?: EqualityChecker<T>): T;
17
15
  export declare function useFrame(callback: RenderCallback, renderPriority?: number): null;
18
16
  export declare function useGraph(object: THREE.Object3D): ObjectMap;
19
- export declare function useMemoizedFn<T extends noop>(fn?: T): PickFunction<T>;
20
17
  export declare function useLoader<T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U, extensions?: Extensions, onProgress?: (event: ProgressEvent<EventTarget>) => void): U extends any[] ? BranchingReturn<T, GLTF, GLTF & ObjectMap>[] : BranchingReturn<T, GLTF, GLTF & ObjectMap>;
21
18
  export declare namespace useLoader {
22
19
  var preload: <T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U, extensions?: Extensions | undefined) => undefined;
23
20
  var clear: <T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U) => void;
24
21
  }
25
- export {};
@@ -2,7 +2,8 @@
2
2
  import * as THREE from 'three';
3
3
  import * as React from 'react';
4
4
  import { UseBoundStore } from 'zustand';
5
- import { Renderer, StoreProps, context, RootState, Size } from './store';
5
+ import * as ReactThreeFiber from '../three-types';
6
+ import { Renderer, context, RootState, Size, Camera, Dpr, Performance } from './store';
6
7
  import { extend, Root } from './renderer';
7
8
  import { addEffect, addAfterEffect, addTail } from './loop';
8
9
  import { EventManager, ComputeFunction } from './events';
@@ -14,11 +15,24 @@ declare type Properties<T> = Pick<T, {
14
15
  [K in keyof T]: T[K] extends (_: any) => any ? never : K;
15
16
  }[keyof T]>;
16
17
  declare type GLProps = Renderer | ((canvas: HTMLCanvasElement) => Renderer) | Partial<Properties<THREE.WebGLRenderer> | THREE.WebGLRendererParameters> | undefined;
17
- export declare type RenderProps<TCanvas extends Element> = Omit<StoreProps, 'gl' | 'events' | 'size'> & {
18
+ export declare type RenderProps<TCanvas extends Element> = {
18
19
  gl?: GLProps;
19
- events?: (store: UseBoundStore<RootState>) => EventManager<TCanvas>;
20
20
  size?: Size;
21
+ shadows?: boolean | Partial<THREE.WebGLShadowMap>;
22
+ legacy?: boolean;
23
+ linear?: boolean;
24
+ flat?: boolean;
25
+ orthographic?: boolean;
26
+ frameloop?: 'always' | 'demand' | 'never';
27
+ performance?: Partial<Omit<Performance, 'regress'>>;
28
+ dpr?: Dpr;
29
+ raycaster?: Partial<THREE.Raycaster>;
30
+ camera?: (Camera | Partial<ReactThreeFiber.Object3DNode<THREE.Camera, typeof THREE.Camera> & ReactThreeFiber.Object3DNode<THREE.PerspectiveCamera, typeof THREE.PerspectiveCamera> & ReactThreeFiber.Object3DNode<THREE.OrthographicCamera, typeof THREE.OrthographicCamera>>) & {
31
+ manual?: boolean;
32
+ };
33
+ events?: (store: UseBoundStore<RootState>) => EventManager<HTMLElement>;
21
34
  onCreated?: (state: RootState) => void;
35
+ onPointerMissed?: (event: MouseEvent) => void;
22
36
  };
23
37
  export declare type ReconcilerRoot<TCanvas extends Element> = {
24
38
  configure: (config?: RenderProps<TCanvas>) => ReconcilerRoot<TCanvas>;
@@ -1,6 +1,5 @@
1
1
  import * as THREE from 'three';
2
2
  import * as React from 'react';
3
- import * as ReactThreeFiber from '../three-types';
4
3
  import { GetState, SetState, StoreApi, UseBoundStore } from 'zustand';
5
4
  import { DomEvent, EventManager, PointerCaptureTarget, ThreeEvent } from './events';
6
5
  export interface Intersection extends THREE.Intersection {
@@ -87,23 +86,6 @@ export declare type RootState = {
87
86
  previousRoot?: UseBoundStore<RootState, StoreApi<RootState>>;
88
87
  internal: InternalState;
89
88
  };
90
- export declare type StoreProps = {
91
- gl: THREE.WebGLRenderer;
92
- size: Size;
93
- shadows?: boolean | Partial<THREE.WebGLShadowMap>;
94
- legacy?: boolean;
95
- linear?: boolean;
96
- flat?: boolean;
97
- orthographic?: boolean;
98
- frameloop?: 'always' | 'demand' | 'never';
99
- performance?: Partial<Omit<Performance, 'regress'>>;
100
- dpr?: Dpr;
101
- raycaster?: Partial<THREE.Raycaster>;
102
- camera?: (Camera | Partial<ReactThreeFiber.Object3DNode<THREE.Camera, typeof THREE.Camera> & ReactThreeFiber.Object3DNode<THREE.PerspectiveCamera, typeof THREE.PerspectiveCamera> & ReactThreeFiber.Object3DNode<THREE.OrthographicCamera, typeof THREE.OrthographicCamera>>) & {
103
- manual?: boolean;
104
- };
105
- onPointerMissed?: (event: MouseEvent) => void;
106
- };
107
89
  declare const context: React.Context<UseBoundStore<RootState, StoreApi<RootState>>>;
108
90
  declare const createStore: (invalidate: (state?: RootState | undefined) => void, advance: (timestamp: number, runGlobalEffects?: boolean | undefined, state?: RootState | undefined, frame?: THREE.XRFrame | undefined) => void) => UseBoundStore<RootState>;
109
91
  export { createStore, context };
@@ -1,6 +1,29 @@
1
1
  import * as THREE from 'three';
2
+ import * as React from 'react';
2
3
  import { AttachType, Instance, InstanceProps, LocalState } from './renderer';
3
4
  import { Dpr, RootState } from './store';
5
+ export declare const useIsomorphicLayoutEffect: typeof React.useEffect;
6
+ export declare function useMutableCallback<T>(fn: T): React.MutableRefObject<T>;
7
+ export declare type SetBlock = false | Promise<null> | null;
8
+ export declare type UnblockProps = {
9
+ set: React.Dispatch<React.SetStateAction<SetBlock>>;
10
+ children: React.ReactNode;
11
+ };
12
+ export declare function Block({ set }: Omit<UnblockProps, 'children'>): null;
13
+ export declare class ErrorBoundary extends React.Component<{
14
+ set: React.Dispatch<any>;
15
+ }, {
16
+ error: boolean;
17
+ }> {
18
+ state: {
19
+ error: boolean;
20
+ };
21
+ static getDerivedStateFromError: () => {
22
+ error: boolean;
23
+ };
24
+ componentDidCatch(error: any): void;
25
+ render(): React.ReactNode;
26
+ }
4
27
  export declare const DEFAULT = "__default";
5
28
  export declare type DiffSet = {
6
29
  memoized: {
@@ -1,13 +1,8 @@
1
1
  import * as React from 'react';
2
2
  import { View, ViewProps, ViewStyle } from 'react-native';
3
- import { UseBoundStore } from 'zustand';
4
3
  import { RenderProps } from '../core';
5
- import { RootState } from '../core/store';
6
- import { EventManager } from '../core/events';
7
- export interface Props extends Omit<RenderProps<HTMLCanvasElement>, 'size' | 'events'>, ViewProps {
4
+ export interface Props extends Omit<RenderProps<HTMLCanvasElement>, 'size'>, ViewProps {
8
5
  children: React.ReactNode;
9
- fallback?: React.ReactNode;
10
6
  style?: ViewStyle;
11
- events?: (store: UseBoundStore<RootState>) => EventManager<any>;
12
7
  }
13
8
  export declare const Canvas: React.ForwardRefExoticComponent<Props & React.RefAttributes<View>>;
@@ -1,5 +1,4 @@
1
1
  import { UseBoundStore } from 'zustand';
2
2
  import { RootState } from '../core/store';
3
3
  import { EventManager } from '../core/events';
4
- import { View } from 'react-native';
5
- export declare function createTouchEvents(store: UseBoundStore<RootState>): EventManager<View>;
4
+ export declare function createTouchEvents(store: UseBoundStore<RootState>): EventManager<HTMLElement>;
@@ -1,13 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import type { Options as ResizeOptions } from 'react-use-measure';
3
- import { UseBoundStore } from 'zustand';
4
3
  import { RenderProps } from '../core';
5
- import { RootState } from '../core/store';
6
- import { EventManager } from '../core/events';
7
- export interface Props extends Omit<RenderProps<HTMLCanvasElement>, 'size' | 'events'>, React.HTMLAttributes<HTMLDivElement> {
4
+ export interface Props extends Omit<RenderProps<HTMLCanvasElement>, 'size'>, React.HTMLAttributes<HTMLDivElement> {
8
5
  children: React.ReactNode;
9
6
  fallback?: React.ReactNode;
10
7
  resize?: ResizeOptions;
11
- events?: (store: UseBoundStore<RootState>) => EventManager<any>;
12
8
  }
13
9
  export declare const Canvas: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLCanvasElement>>;
@@ -39,6 +39,47 @@ var threeTypes = /*#__PURE__*/Object.freeze({
39
39
  __proto__: null
40
40
  });
41
41
 
42
+ // React currently throws a warning when using useLayoutEffect on the server.
43
+ // To get around it, we can conditionally useEffect on the server (no-op) and
44
+ // useLayoutEffect on the client.
45
+ const isSSR = typeof window === 'undefined' || !window.navigator || /ServerSideRendering|^Deno\//.test(window.navigator.userAgent);
46
+ const useIsomorphicLayoutEffect = isSSR ? React__namespace.useEffect : React__namespace.useLayoutEffect;
47
+ function useMutableCallback(fn) {
48
+ const ref = React__namespace.useRef(fn);
49
+ useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
50
+ return ref;
51
+ }
52
+ function Block({
53
+ set
54
+ }) {
55
+ useIsomorphicLayoutEffect(() => {
56
+ set(new Promise(() => null));
57
+ return () => set(false);
58
+ }, [set]);
59
+ return null;
60
+ }
61
+ class ErrorBoundary extends React__namespace.Component {
62
+ constructor(...args) {
63
+ super(...args);
64
+ this.state = {
65
+ error: false
66
+ };
67
+ }
68
+
69
+ componentDidCatch(error) {
70
+ this.props.set(error);
71
+ }
72
+
73
+ render() {
74
+ return this.state.error ? null : this.props.children;
75
+ }
76
+
77
+ }
78
+
79
+ ErrorBoundary.getDerivedStateFromError = () => ({
80
+ error: true
81
+ });
82
+
42
83
  const DEFAULT = '__default';
43
84
  const isDiffSet = def => def && !!def.memoized && !!def.changes;
44
85
  function calculateDpr(dpr) {
@@ -1396,8 +1437,23 @@ let i;
1396
1437
  let globalEffects = [];
1397
1438
  let globalAfterEffects = [];
1398
1439
  let globalTailEffects = [];
1440
+ /**
1441
+ * Adds a global render callback which is called each frame.
1442
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
1443
+ */
1444
+
1399
1445
  const addEffect = callback => createSubs(callback, globalEffects);
1446
+ /**
1447
+ * Adds a global after-render callback which is called each frame.
1448
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
1449
+ */
1450
+
1400
1451
  const addAfterEffect = callback => createSubs(callback, globalAfterEffects);
1452
+ /**
1453
+ * Adds a global callback which is called when rendering stops.
1454
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
1455
+ */
1456
+
1401
1457
  const addTail = callback => createSubs(callback, globalTailEffects);
1402
1458
 
1403
1459
  function run(effects, timestamp) {
@@ -1488,7 +1544,17 @@ function createLoop(roots) {
1488
1544
 
1489
1545
  return {
1490
1546
  loop,
1547
+
1548
+ /**
1549
+ * Invalidates the view, requesting a frame to be rendered. Will globally invalidate unless passed a root's state.
1550
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#invalidate
1551
+ */
1491
1552
  invalidate,
1553
+
1554
+ /**
1555
+ * Advances the frameloop and runs render effects, useful for when manually rendering via `frameloop="never"`.
1556
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#advance
1557
+ */
1492
1558
  advance
1493
1559
  };
1494
1560
  }
@@ -1498,19 +1564,34 @@ function useStore() {
1498
1564
  if (!store) throw `R3F hooks can only be used within the Canvas component!`;
1499
1565
  return store;
1500
1566
  }
1567
+ /**
1568
+ * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1569
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1570
+ */
1571
+
1501
1572
  function useThree(selector = state => state, equalityFn) {
1502
1573
  return useStore()(selector, equalityFn);
1503
1574
  }
1575
+ /**
1576
+ * Executes a callback before render in a shared frame loop.
1577
+ * Can order effects with render priority or manually render with a positive priority.
1578
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1579
+ */
1580
+
1504
1581
  function useFrame(callback, renderPriority = 0) {
1505
1582
  const store = useStore();
1506
- const subscribe = store.getState().internal.subscribe; // Update ref
1583
+ const subscribe = store.getState().internal.subscribe; // Memoize ref
1507
1584
 
1508
- const ref = React__namespace.useRef(callback);
1509
- React__namespace.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe on mount, unsubscribe on unmount
1585
+ const ref = useMutableCallback(callback); // Subscribe on mount, unsubscribe on unmount
1510
1586
 
1511
- React__namespace.useLayoutEffect(() => subscribe(ref, renderPriority, store), [renderPriority, subscribe, store]);
1587
+ useIsomorphicLayoutEffect(() => subscribe(ref, renderPriority, store), [renderPriority, subscribe, store]);
1512
1588
  return null;
1513
1589
  }
1590
+ /**
1591
+ * Returns a node graph of an object with named nodes & materials.
1592
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1593
+ */
1594
+
1514
1595
  function useGraph(object) {
1515
1596
  return React__namespace.useMemo(() => buildGraph(object), [object]);
1516
1597
  }
@@ -1527,12 +1608,14 @@ function loadingFn(extensions, onProgress) {
1527
1608
  }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1528
1609
  };
1529
1610
  }
1611
+ /**
1612
+ * Synchronously loads and caches assets with a three loader.
1613
+ *
1614
+ * Note: this hook's caller must be wrapped with `React.Suspense`
1615
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1616
+ */
1617
+
1530
1618
 
1531
- function useMemoizedFn(fn) {
1532
- const fnRef = React__namespace.useRef(fn);
1533
- React__namespace.useLayoutEffect(() => void (fnRef.current = fn), [fn]);
1534
- return (...args) => fnRef.current == null ? void 0 : fnRef.current(...args);
1535
- }
1536
1619
  function useLoader(Proto, input, extensions, onProgress) {
1537
1620
  // Use suspense to load async assets
1538
1621
  const keys = Array.isArray(input) ? input : [input];
@@ -1542,11 +1625,18 @@ function useLoader(Proto, input, extensions, onProgress) {
1542
1625
 
1543
1626
  return Array.isArray(input) ? results : results[0];
1544
1627
  }
1628
+ /**
1629
+ * Preloads an asset into cache as a side-effect.
1630
+ */
1545
1631
 
1546
1632
  useLoader.preload = function (Proto, input, extensions) {
1547
1633
  const keys = Array.isArray(input) ? input : [input];
1548
1634
  return suspendReact.preload(loadingFn(extensions), [Proto, ...keys]);
1549
1635
  };
1636
+ /**
1637
+ * Removes a loaded asset from cache.
1638
+ */
1639
+
1550
1640
 
1551
1641
  useLoader.clear = function (Proto, input) {
1552
1642
  const keys = Array.isArray(input) ? input : [input];
@@ -1793,7 +1883,7 @@ function Provider({
1793
1883
  onCreated,
1794
1884
  rootElement
1795
1885
  }) {
1796
- React__namespace.useLayoutEffect(() => {
1886
+ useIsomorphicLayoutEffect(() => {
1797
1887
  const state = store.getState(); // Flag the canvas active, rendering will now begin
1798
1888
 
1799
1889
  state.set(state => ({
@@ -1921,6 +2011,8 @@ reconciler.injectIntoDevTools({
1921
2011
  });
1922
2012
  const act = React__namespace.unstable_act;
1923
2013
 
2014
+ exports.Block = Block;
2015
+ exports.ErrorBoundary = ErrorBoundary;
1924
2016
  exports.act = act;
1925
2017
  exports.addAfterEffect = addAfterEffect;
1926
2018
  exports.addEffect = addEffect;
@@ -1944,7 +2036,8 @@ exports.threeTypes = threeTypes;
1944
2036
  exports.unmountComponentAtNode = unmountComponentAtNode;
1945
2037
  exports.useFrame = useFrame;
1946
2038
  exports.useGraph = useGraph;
2039
+ exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
1947
2040
  exports.useLoader = useLoader;
1948
- exports.useMemoizedFn = useMemoizedFn;
2041
+ exports.useMutableCallback = useMutableCallback;
1949
2042
  exports.useStore = useStore;
1950
2043
  exports.useThree = useThree;
@@ -39,6 +39,47 @@ var threeTypes = /*#__PURE__*/Object.freeze({
39
39
  __proto__: null
40
40
  });
41
41
 
42
+ // React currently throws a warning when using useLayoutEffect on the server.
43
+ // To get around it, we can conditionally useEffect on the server (no-op) and
44
+ // useLayoutEffect on the client.
45
+ const isSSR = typeof window === 'undefined' || !window.navigator || /ServerSideRendering|^Deno\//.test(window.navigator.userAgent);
46
+ const useIsomorphicLayoutEffect = isSSR ? React__namespace.useEffect : React__namespace.useLayoutEffect;
47
+ function useMutableCallback(fn) {
48
+ const ref = React__namespace.useRef(fn);
49
+ useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
50
+ return ref;
51
+ }
52
+ function Block({
53
+ set
54
+ }) {
55
+ useIsomorphicLayoutEffect(() => {
56
+ set(new Promise(() => null));
57
+ return () => set(false);
58
+ }, [set]);
59
+ return null;
60
+ }
61
+ class ErrorBoundary extends React__namespace.Component {
62
+ constructor(...args) {
63
+ super(...args);
64
+ this.state = {
65
+ error: false
66
+ };
67
+ }
68
+
69
+ componentDidCatch(error) {
70
+ this.props.set(error);
71
+ }
72
+
73
+ render() {
74
+ return this.state.error ? null : this.props.children;
75
+ }
76
+
77
+ }
78
+
79
+ ErrorBoundary.getDerivedStateFromError = () => ({
80
+ error: true
81
+ });
82
+
42
83
  const DEFAULT = '__default';
43
84
  const isDiffSet = def => def && !!def.memoized && !!def.changes;
44
85
  function calculateDpr(dpr) {
@@ -1396,8 +1437,23 @@ let i;
1396
1437
  let globalEffects = [];
1397
1438
  let globalAfterEffects = [];
1398
1439
  let globalTailEffects = [];
1440
+ /**
1441
+ * Adds a global render callback which is called each frame.
1442
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
1443
+ */
1444
+
1399
1445
  const addEffect = callback => createSubs(callback, globalEffects);
1446
+ /**
1447
+ * Adds a global after-render callback which is called each frame.
1448
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
1449
+ */
1450
+
1400
1451
  const addAfterEffect = callback => createSubs(callback, globalAfterEffects);
1452
+ /**
1453
+ * Adds a global callback which is called when rendering stops.
1454
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
1455
+ */
1456
+
1401
1457
  const addTail = callback => createSubs(callback, globalTailEffects);
1402
1458
 
1403
1459
  function run(effects, timestamp) {
@@ -1488,7 +1544,17 @@ function createLoop(roots) {
1488
1544
 
1489
1545
  return {
1490
1546
  loop,
1547
+
1548
+ /**
1549
+ * Invalidates the view, requesting a frame to be rendered. Will globally invalidate unless passed a root's state.
1550
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#invalidate
1551
+ */
1491
1552
  invalidate,
1553
+
1554
+ /**
1555
+ * Advances the frameloop and runs render effects, useful for when manually rendering via `frameloop="never"`.
1556
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#advance
1557
+ */
1492
1558
  advance
1493
1559
  };
1494
1560
  }
@@ -1498,19 +1564,34 @@ function useStore() {
1498
1564
  if (!store) throw `R3F hooks can only be used within the Canvas component!`;
1499
1565
  return store;
1500
1566
  }
1567
+ /**
1568
+ * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1569
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1570
+ */
1571
+
1501
1572
  function useThree(selector = state => state, equalityFn) {
1502
1573
  return useStore()(selector, equalityFn);
1503
1574
  }
1575
+ /**
1576
+ * Executes a callback before render in a shared frame loop.
1577
+ * Can order effects with render priority or manually render with a positive priority.
1578
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1579
+ */
1580
+
1504
1581
  function useFrame(callback, renderPriority = 0) {
1505
1582
  const store = useStore();
1506
- const subscribe = store.getState().internal.subscribe; // Update ref
1583
+ const subscribe = store.getState().internal.subscribe; // Memoize ref
1507
1584
 
1508
- const ref = React__namespace.useRef(callback);
1509
- React__namespace.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe on mount, unsubscribe on unmount
1585
+ const ref = useMutableCallback(callback); // Subscribe on mount, unsubscribe on unmount
1510
1586
 
1511
- React__namespace.useLayoutEffect(() => subscribe(ref, renderPriority, store), [renderPriority, subscribe, store]);
1587
+ useIsomorphicLayoutEffect(() => subscribe(ref, renderPriority, store), [renderPriority, subscribe, store]);
1512
1588
  return null;
1513
1589
  }
1590
+ /**
1591
+ * Returns a node graph of an object with named nodes & materials.
1592
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1593
+ */
1594
+
1514
1595
  function useGraph(object) {
1515
1596
  return React__namespace.useMemo(() => buildGraph(object), [object]);
1516
1597
  }
@@ -1527,12 +1608,14 @@ function loadingFn(extensions, onProgress) {
1527
1608
  }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1528
1609
  };
1529
1610
  }
1611
+ /**
1612
+ * Synchronously loads and caches assets with a three loader.
1613
+ *
1614
+ * Note: this hook's caller must be wrapped with `React.Suspense`
1615
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1616
+ */
1617
+
1530
1618
 
1531
- function useMemoizedFn(fn) {
1532
- const fnRef = React__namespace.useRef(fn);
1533
- React__namespace.useLayoutEffect(() => void (fnRef.current = fn), [fn]);
1534
- return (...args) => fnRef.current == null ? void 0 : fnRef.current(...args);
1535
- }
1536
1619
  function useLoader(Proto, input, extensions, onProgress) {
1537
1620
  // Use suspense to load async assets
1538
1621
  const keys = Array.isArray(input) ? input : [input];
@@ -1542,11 +1625,18 @@ function useLoader(Proto, input, extensions, onProgress) {
1542
1625
 
1543
1626
  return Array.isArray(input) ? results : results[0];
1544
1627
  }
1628
+ /**
1629
+ * Preloads an asset into cache as a side-effect.
1630
+ */
1545
1631
 
1546
1632
  useLoader.preload = function (Proto, input, extensions) {
1547
1633
  const keys = Array.isArray(input) ? input : [input];
1548
1634
  return suspendReact.preload(loadingFn(extensions), [Proto, ...keys]);
1549
1635
  };
1636
+ /**
1637
+ * Removes a loaded asset from cache.
1638
+ */
1639
+
1550
1640
 
1551
1641
  useLoader.clear = function (Proto, input) {
1552
1642
  const keys = Array.isArray(input) ? input : [input];
@@ -1793,7 +1883,7 @@ function Provider({
1793
1883
  onCreated,
1794
1884
  rootElement
1795
1885
  }) {
1796
- React__namespace.useLayoutEffect(() => {
1886
+ useIsomorphicLayoutEffect(() => {
1797
1887
  const state = store.getState(); // Flag the canvas active, rendering will now begin
1798
1888
 
1799
1889
  state.set(state => ({
@@ -1921,6 +2011,8 @@ reconciler.injectIntoDevTools({
1921
2011
  });
1922
2012
  const act = React__namespace.unstable_act;
1923
2013
 
2014
+ exports.Block = Block;
2015
+ exports.ErrorBoundary = ErrorBoundary;
1924
2016
  exports.act = act;
1925
2017
  exports.addAfterEffect = addAfterEffect;
1926
2018
  exports.addEffect = addEffect;
@@ -1944,7 +2036,8 @@ exports.threeTypes = threeTypes;
1944
2036
  exports.unmountComponentAtNode = unmountComponentAtNode;
1945
2037
  exports.useFrame = useFrame;
1946
2038
  exports.useGraph = useGraph;
2039
+ exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
1947
2040
  exports.useLoader = useLoader;
1948
- exports.useMemoizedFn = useMemoizedFn;
2041
+ exports.useMutableCallback = useMutableCallback;
1949
2042
  exports.useStore = useStore;
1950
2043
  exports.useThree = useThree;