@react-three/fiber 9.0.0-alpha.0 → 9.0.0-alpha.1

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,17 @@
1
1
  # @react-three/fiber
2
2
 
3
+ ## 8.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 9c450ec: feat: improve errors
8
+
9
+ ## 8.2.3
10
+
11
+ ### Patch Changes
12
+
13
+ - b8d2eab: fix: improve useLoader signature, initial size on createRoot
14
+
3
15
  ## 8.2.2
4
16
 
5
17
  ### Patch Changes
@@ -4,6 +4,7 @@ import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader';
4
4
  import { RootState, RenderCallback, StageTypes } from './store';
5
5
  import { ObjectMap } from './utils';
6
6
  import { UpdateCallback } from './stages';
7
+ import { LoadingManager } from 'three';
7
8
  export interface Loader<T> extends THREE.Loader {
8
9
  load(url: string, onLoad?: (result: T) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): unknown;
9
10
  }
@@ -16,7 +17,7 @@ export declare function useThree<T = RootState>(selector?: StateSelector<RootSta
16
17
  export declare function useFrame(callback: RenderCallback, renderPriority?: number): null;
17
18
  export declare function useUpdate(callback: UpdateCallback, stage?: StageTypes): void;
18
19
  export declare function useGraph(object: THREE.Object3D): ObjectMap;
19
- 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>;
20
+ export declare function useLoader<T, U extends string | string[]>(Proto: new (manager?: LoadingManager) => LoaderResult<T>, input: U, extensions?: Extensions, onProgress?: (event: ProgressEvent<EventTarget>) => void): U extends any[] ? BranchingReturn<T, GLTF, GLTF & ObjectMap>[] : BranchingReturn<T, GLTF, GLTF & ObjectMap>;
20
21
  export declare namespace useLoader {
21
22
  var preload: <T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U, extensions?: Extensions | undefined) => undefined;
22
23
  var clear: <T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U) => void;
@@ -13,7 +13,7 @@ export declare type UnblockProps = {
13
13
  };
14
14
  export declare function Block({ set }: Omit<UnblockProps, 'children'>): null;
15
15
  export declare class ErrorBoundary extends React.Component<{
16
- set: React.Dispatch<any>;
16
+ set: React.Dispatch<Error | undefined>;
17
17
  children: React.ReactNode;
18
18
  }, {
19
19
  error: boolean;
@@ -24,7 +24,7 @@ export declare class ErrorBoundary extends React.Component<{
24
24
  static getDerivedStateFromError: () => {
25
25
  error: boolean;
26
26
  };
27
- componentDidCatch(error: any): void;
27
+ componentDidCatch(err: Error): void;
28
28
  render(): React.ReactNode;
29
29
  }
30
30
  export declare const DEFAULT = "__default";
@@ -1,8 +1,8 @@
1
1
  import * as React from 'react';
2
2
  import { View, ViewProps, ViewStyle } from 'react-native';
3
3
  import { RenderProps } from '../core';
4
- export interface Props extends Omit<RenderProps<HTMLCanvasElement>, 'size' | 'dpr'>, ViewProps {
4
+ export interface CanvasProps extends Omit<RenderProps<HTMLCanvasElement>, 'size' | 'dpr'>, ViewProps {
5
5
  children: React.ReactNode;
6
6
  style?: ViewStyle;
7
7
  }
8
- export declare const Canvas: React.ForwardRefExoticComponent<Props & React.RefAttributes<View>>;
8
+ export declare const Canvas: React.ForwardRefExoticComponent<CanvasProps & React.RefAttributes<View>>;
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import type { Options as ResizeOptions } from 'react-use-measure';
3
3
  import { RenderProps } from '../core';
4
- export interface Props extends Omit<RenderProps<HTMLCanvasElement>, 'size'>, React.HTMLAttributes<HTMLDivElement> {
4
+ export interface CanvasProps extends Omit<RenderProps<HTMLCanvasElement>, 'size'>, React.HTMLAttributes<HTMLDivElement> {
5
5
  children: React.ReactNode;
6
6
  fallback?: React.ReactNode;
7
7
  resize?: ResizeOptions;
8
8
  }
9
- export declare const Canvas: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLCanvasElement>>;
9
+ export declare const Canvas: React.ForwardRefExoticComponent<CanvasProps & React.RefAttributes<HTMLCanvasElement>>;
@@ -72,8 +72,8 @@ class ErrorBoundary extends React__namespace.Component {
72
72
  };
73
73
  }
74
74
 
75
- componentDidCatch(error) {
76
- this.props.set(error);
75
+ componentDidCatch(err) {
76
+ this.props.set(err);
77
77
  }
78
78
 
79
79
  render() {
@@ -862,7 +862,7 @@ function createRenderer(_roots, _getEventPriority) {
862
862
  }
863
863
 
864
864
  if (type === 'primitive') {
865
- if (props.object === undefined) throw `Primitives without 'object' are invalid!`;
865
+ if (props.object === undefined) throw new Error("R3F: Primitives without 'object' are invalid!");
866
866
  const object = props.object;
867
867
  instance = prepare(object, {
868
868
  type,
@@ -874,11 +874,11 @@ function createRenderer(_roots, _getEventPriority) {
874
874
  const target = catalogue[name];
875
875
 
876
876
  if (!target) {
877
- throw `${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`;
877
+ throw new Error(`R3F: ${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`);
878
878
  } // Throw if an object or literal was passed for args
879
879
 
880
880
 
881
- if (!Array.isArray(args)) throw 'The args prop must be an array!'; // Instanciate new object, link it to the root
881
+ if (!Array.isArray(args)) throw new Error('R3F: The args prop must be an array!'); // Instanciate new object, link it to the root
882
882
  // Append memoized props with args so it's not forgotten
883
883
 
884
884
  instance = prepare(new target(...args), {
@@ -1116,7 +1116,7 @@ function createRenderer(_roots, _getEventPriority) {
1116
1116
  ...restOld
1117
1117
  } = oldProps; // Throw if an object or literal was passed for args
1118
1118
 
1119
- if (!Array.isArray(argsNew)) throw 'The args prop must be an array!'; // If it has new props or arguments, then it needs to be re-instantiated
1119
+ if (!Array.isArray(argsNew)) throw new Error('R3F: the args prop must be an array!'); // If it has new props or arguments, then it needs to be re-instantiated
1120
1120
 
1121
1121
  if (argsNew.some((value, index) => value !== argsOld[index])) return [true]; // Create a diff-set, flag if there are any changes
1122
1122
 
@@ -1748,7 +1748,7 @@ const Lifecycle = [Early, Fixed, Update, Late, Render, After];
1748
1748
 
1749
1749
  function useStore() {
1750
1750
  const store = React__namespace.useContext(context);
1751
- if (!store) throw `R3F hooks can only be used within the Canvas component!`;
1751
+ if (!store) throw new Error('R3F: Hooks can only be used within the Canvas component!');
1752
1752
  return store;
1753
1753
  }
1754
1754
  /**
@@ -1807,7 +1807,7 @@ function loadingFn(extensions, onProgress) {
1807
1807
  return Promise.all(input.map(input => new Promise((res, reject) => loader.load(input, data => {
1808
1808
  if (data.scene) Object.assign(data, buildGraph(data.scene));
1809
1809
  res(data);
1810
- }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1810
+ }, onProgress, error => reject(new Error(`Could not load ${input}: ${error.message})`))))));
1811
1811
  };
1812
1812
  }
1813
1813
  /**
@@ -1871,19 +1871,19 @@ const createRendererInstance = (gl, canvas) => {
1871
1871
  };
1872
1872
 
1873
1873
  const createStages = (stages, store) => {
1874
- var _stages;
1875
-
1876
1874
  const state = store.getState();
1877
1875
  let subscribers;
1878
1876
  let subscription;
1879
- stages = (_stages = stages) != null ? _stages : Lifecycle;
1880
- if (!stages.includes(Stages.Update)) throw 'The Stages.Update stage is required for R3F.';
1881
- if (!stages.includes(Stages.Render)) throw 'The Stages.Render stage is required for R3F.';
1877
+
1878
+ const _stages = stages != null ? stages : Lifecycle;
1879
+
1880
+ if (!_stages.includes(Stages.Update)) throw 'The Stages.Update stage is required for R3F.';
1881
+ if (!_stages.includes(Stages.Render)) throw 'The Stages.Render stage is required for R3F.';
1882
1882
  state.set(({
1883
1883
  internal
1884
1884
  }) => ({
1885
1885
  internal: { ...internal,
1886
- stages: stages
1886
+ stages: _stages
1887
1887
  }
1888
1888
  })); // Add useFrame loop to update stage
1889
1889
 
@@ -1907,11 +1907,43 @@ const createStages = (stages, store) => {
1907
1907
  Stages.Render.add(renderCallback, store);
1908
1908
  };
1909
1909
 
1910
+ function isCanvas(maybeCanvas) {
1911
+ return maybeCanvas instanceof HTMLCanvasElement;
1912
+ }
1913
+
1914
+ function computeInitialSize(canvas, defaultSize) {
1915
+ if (defaultSize) {
1916
+ return defaultSize;
1917
+ }
1918
+
1919
+ if (isCanvas(canvas) && canvas.parentElement) {
1920
+ const {
1921
+ width,
1922
+ height,
1923
+ top,
1924
+ left
1925
+ } = canvas.parentElement.getBoundingClientRect();
1926
+ return {
1927
+ width,
1928
+ height,
1929
+ top,
1930
+ left
1931
+ };
1932
+ }
1933
+
1934
+ return {
1935
+ width: 0,
1936
+ height: 0,
1937
+ top: 0,
1938
+ left: 0
1939
+ };
1940
+ }
1941
+
1910
1942
  function createRoot(canvas) {
1911
1943
  // Check against mistaken use of createRoot
1912
- let prevRoot = roots.get(canvas);
1913
- let prevFiber = prevRoot == null ? void 0 : prevRoot.fiber;
1914
- let prevStore = prevRoot == null ? void 0 : prevRoot.store;
1944
+ const prevRoot = roots.get(canvas);
1945
+ const prevFiber = prevRoot == null ? void 0 : prevRoot.fiber;
1946
+ const prevStore = prevRoot == null ? void 0 : prevRoot.store;
1915
1947
  if (prevRoot) console.warn('R3F.createRoot should only be called once!'); // Report when an error was detected in a previous render
1916
1948
  // https://github.com/pmndrs/react-three-fiber/pull/2261
1917
1949
 
@@ -1935,7 +1967,7 @@ function createRoot(canvas) {
1935
1967
  configure(props = {}) {
1936
1968
  let {
1937
1969
  gl: glConfig,
1938
- size,
1970
+ size: propsSize,
1939
1971
  events,
1940
1972
  onCreated: onCreatedCallback,
1941
1973
  shadows = false,
@@ -2065,17 +2097,7 @@ function createRoot(canvas) {
2065
2097
 
2066
2098
  if (dpr && state.viewport.dpr !== calculateDpr(dpr)) state.setDpr(dpr); // Check size, allow it to take on container bounds initially
2067
2099
 
2068
- size = size || (canvas.parentElement ? {
2069
- width: canvas.parentElement.clientWidth,
2070
- height: canvas.parentElement.clientHeight,
2071
- top: canvas.parentElement.clientTop,
2072
- left: canvas.parentElement.clientLeft
2073
- } : {
2074
- width: 0,
2075
- height: 0,
2076
- top: 0,
2077
- left: 0
2078
- });
2100
+ const size = computeInitialSize(canvas, propsSize);
2079
2101
 
2080
2102
  if (!is.equ(size, state.size, shallowLoose)) {
2081
2103
  state.setSize(size.width, size.height, size.updateStyle, size.top, size.left);
@@ -2092,9 +2114,9 @@ function createRoot(canvas) {
2092
2114
  performance: { ...state.performance,
2093
2115
  ...performance
2094
2116
  }
2095
- })); // Create update stages.
2117
+ })); // Create update stages. Only do this once on init
2096
2118
 
2097
- if (stages !== state.internal.stages) createStages(stages, store); // Set locals
2119
+ if (state.internal.stages.length === 0) createStages(stages, store); // Set locals
2098
2120
 
2099
2121
  onCreated = onCreatedCallback;
2100
2122
  configured = true;
@@ -72,8 +72,8 @@ class ErrorBoundary extends React__namespace.Component {
72
72
  };
73
73
  }
74
74
 
75
- componentDidCatch(error) {
76
- this.props.set(error);
75
+ componentDidCatch(err) {
76
+ this.props.set(err);
77
77
  }
78
78
 
79
79
  render() {
@@ -862,7 +862,7 @@ function createRenderer(_roots, _getEventPriority) {
862
862
  }
863
863
 
864
864
  if (type === 'primitive') {
865
- if (props.object === undefined) throw `Primitives without 'object' are invalid!`;
865
+ if (props.object === undefined) throw new Error("R3F: Primitives without 'object' are invalid!");
866
866
  const object = props.object;
867
867
  instance = prepare(object, {
868
868
  type,
@@ -874,11 +874,11 @@ function createRenderer(_roots, _getEventPriority) {
874
874
  const target = catalogue[name];
875
875
 
876
876
  if (!target) {
877
- throw `${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`;
877
+ throw new Error(`R3F: ${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`);
878
878
  } // Throw if an object or literal was passed for args
879
879
 
880
880
 
881
- if (!Array.isArray(args)) throw 'The args prop must be an array!'; // Instanciate new object, link it to the root
881
+ if (!Array.isArray(args)) throw new Error('R3F: The args prop must be an array!'); // Instanciate new object, link it to the root
882
882
  // Append memoized props with args so it's not forgotten
883
883
 
884
884
  instance = prepare(new target(...args), {
@@ -1116,7 +1116,7 @@ function createRenderer(_roots, _getEventPriority) {
1116
1116
  ...restOld
1117
1117
  } = oldProps; // Throw if an object or literal was passed for args
1118
1118
 
1119
- if (!Array.isArray(argsNew)) throw 'The args prop must be an array!'; // If it has new props or arguments, then it needs to be re-instantiated
1119
+ if (!Array.isArray(argsNew)) throw new Error('R3F: the args prop must be an array!'); // If it has new props or arguments, then it needs to be re-instantiated
1120
1120
 
1121
1121
  if (argsNew.some((value, index) => value !== argsOld[index])) return [true]; // Create a diff-set, flag if there are any changes
1122
1122
 
@@ -1748,7 +1748,7 @@ const Lifecycle = [Early, Fixed, Update, Late, Render, After];
1748
1748
 
1749
1749
  function useStore() {
1750
1750
  const store = React__namespace.useContext(context);
1751
- if (!store) throw `R3F hooks can only be used within the Canvas component!`;
1751
+ if (!store) throw new Error('R3F: Hooks can only be used within the Canvas component!');
1752
1752
  return store;
1753
1753
  }
1754
1754
  /**
@@ -1807,7 +1807,7 @@ function loadingFn(extensions, onProgress) {
1807
1807
  return Promise.all(input.map(input => new Promise((res, reject) => loader.load(input, data => {
1808
1808
  if (data.scene) Object.assign(data, buildGraph(data.scene));
1809
1809
  res(data);
1810
- }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1810
+ }, onProgress, error => reject(new Error(`Could not load ${input}: ${error.message})`))))));
1811
1811
  };
1812
1812
  }
1813
1813
  /**
@@ -1871,19 +1871,19 @@ const createRendererInstance = (gl, canvas) => {
1871
1871
  };
1872
1872
 
1873
1873
  const createStages = (stages, store) => {
1874
- var _stages;
1875
-
1876
1874
  const state = store.getState();
1877
1875
  let subscribers;
1878
1876
  let subscription;
1879
- stages = (_stages = stages) != null ? _stages : Lifecycle;
1880
- if (!stages.includes(Stages.Update)) throw 'The Stages.Update stage is required for R3F.';
1881
- if (!stages.includes(Stages.Render)) throw 'The Stages.Render stage is required for R3F.';
1877
+
1878
+ const _stages = stages != null ? stages : Lifecycle;
1879
+
1880
+ if (!_stages.includes(Stages.Update)) throw 'The Stages.Update stage is required for R3F.';
1881
+ if (!_stages.includes(Stages.Render)) throw 'The Stages.Render stage is required for R3F.';
1882
1882
  state.set(({
1883
1883
  internal
1884
1884
  }) => ({
1885
1885
  internal: { ...internal,
1886
- stages: stages
1886
+ stages: _stages
1887
1887
  }
1888
1888
  })); // Add useFrame loop to update stage
1889
1889
 
@@ -1907,11 +1907,43 @@ const createStages = (stages, store) => {
1907
1907
  Stages.Render.add(renderCallback, store);
1908
1908
  };
1909
1909
 
1910
+ function isCanvas(maybeCanvas) {
1911
+ return maybeCanvas instanceof HTMLCanvasElement;
1912
+ }
1913
+
1914
+ function computeInitialSize(canvas, defaultSize) {
1915
+ if (defaultSize) {
1916
+ return defaultSize;
1917
+ }
1918
+
1919
+ if (isCanvas(canvas) && canvas.parentElement) {
1920
+ const {
1921
+ width,
1922
+ height,
1923
+ top,
1924
+ left
1925
+ } = canvas.parentElement.getBoundingClientRect();
1926
+ return {
1927
+ width,
1928
+ height,
1929
+ top,
1930
+ left
1931
+ };
1932
+ }
1933
+
1934
+ return {
1935
+ width: 0,
1936
+ height: 0,
1937
+ top: 0,
1938
+ left: 0
1939
+ };
1940
+ }
1941
+
1910
1942
  function createRoot(canvas) {
1911
1943
  // Check against mistaken use of createRoot
1912
- let prevRoot = roots.get(canvas);
1913
- let prevFiber = prevRoot == null ? void 0 : prevRoot.fiber;
1914
- let prevStore = prevRoot == null ? void 0 : prevRoot.store;
1944
+ const prevRoot = roots.get(canvas);
1945
+ const prevFiber = prevRoot == null ? void 0 : prevRoot.fiber;
1946
+ const prevStore = prevRoot == null ? void 0 : prevRoot.store;
1915
1947
  if (prevRoot) console.warn('R3F.createRoot should only be called once!'); // Report when an error was detected in a previous render
1916
1948
  // https://github.com/pmndrs/react-three-fiber/pull/2261
1917
1949
 
@@ -1935,7 +1967,7 @@ function createRoot(canvas) {
1935
1967
  configure(props = {}) {
1936
1968
  let {
1937
1969
  gl: glConfig,
1938
- size,
1970
+ size: propsSize,
1939
1971
  events,
1940
1972
  onCreated: onCreatedCallback,
1941
1973
  shadows = false,
@@ -2065,17 +2097,7 @@ function createRoot(canvas) {
2065
2097
 
2066
2098
  if (dpr && state.viewport.dpr !== calculateDpr(dpr)) state.setDpr(dpr); // Check size, allow it to take on container bounds initially
2067
2099
 
2068
- size = size || (canvas.parentElement ? {
2069
- width: canvas.parentElement.clientWidth,
2070
- height: canvas.parentElement.clientHeight,
2071
- top: canvas.parentElement.clientTop,
2072
- left: canvas.parentElement.clientLeft
2073
- } : {
2074
- width: 0,
2075
- height: 0,
2076
- top: 0,
2077
- left: 0
2078
- });
2100
+ const size = computeInitialSize(canvas, propsSize);
2079
2101
 
2080
2102
  if (!is.equ(size, state.size, shallowLoose)) {
2081
2103
  state.setSize(size.width, size.height, size.updateStyle, size.top, size.left);
@@ -2092,9 +2114,9 @@ function createRoot(canvas) {
2092
2114
  performance: { ...state.performance,
2093
2115
  ...performance
2094
2116
  }
2095
- })); // Create update stages.
2117
+ })); // Create update stages. Only do this once on init
2096
2118
 
2097
- if (stages !== state.internal.stages) createStages(stages, store); // Set locals
2119
+ if (state.internal.stages.length === 0) createStages(stages, store); // Set locals
2098
2120
 
2099
2121
  onCreated = onCreatedCallback;
2100
2122
  configured = true;
@@ -45,8 +45,8 @@ class ErrorBoundary extends React.Component {
45
45
  };
46
46
  }
47
47
 
48
- componentDidCatch(error) {
49
- this.props.set(error);
48
+ componentDidCatch(err) {
49
+ this.props.set(err);
50
50
  }
51
51
 
52
52
  render() {
@@ -835,7 +835,7 @@ function createRenderer(_roots, _getEventPriority) {
835
835
  }
836
836
 
837
837
  if (type === 'primitive') {
838
- if (props.object === undefined) throw `Primitives without 'object' are invalid!`;
838
+ if (props.object === undefined) throw new Error("R3F: Primitives without 'object' are invalid!");
839
839
  const object = props.object;
840
840
  instance = prepare(object, {
841
841
  type,
@@ -847,11 +847,11 @@ function createRenderer(_roots, _getEventPriority) {
847
847
  const target = catalogue[name];
848
848
 
849
849
  if (!target) {
850
- throw `${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`;
850
+ throw new Error(`R3F: ${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`);
851
851
  } // Throw if an object or literal was passed for args
852
852
 
853
853
 
854
- if (!Array.isArray(args)) throw 'The args prop must be an array!'; // Instanciate new object, link it to the root
854
+ if (!Array.isArray(args)) throw new Error('R3F: The args prop must be an array!'); // Instanciate new object, link it to the root
855
855
  // Append memoized props with args so it's not forgotten
856
856
 
857
857
  instance = prepare(new target(...args), {
@@ -1089,7 +1089,7 @@ function createRenderer(_roots, _getEventPriority) {
1089
1089
  ...restOld
1090
1090
  } = oldProps; // Throw if an object or literal was passed for args
1091
1091
 
1092
- if (!Array.isArray(argsNew)) throw 'The args prop must be an array!'; // If it has new props or arguments, then it needs to be re-instantiated
1092
+ if (!Array.isArray(argsNew)) throw new Error('R3F: the args prop must be an array!'); // If it has new props or arguments, then it needs to be re-instantiated
1093
1093
 
1094
1094
  if (argsNew.some((value, index) => value !== argsOld[index])) return [true]; // Create a diff-set, flag if there are any changes
1095
1095
 
@@ -1721,7 +1721,7 @@ const Lifecycle = [Early, Fixed, Update, Late, Render, After];
1721
1721
 
1722
1722
  function useStore() {
1723
1723
  const store = React.useContext(context);
1724
- if (!store) throw `R3F hooks can only be used within the Canvas component!`;
1724
+ if (!store) throw new Error('R3F: Hooks can only be used within the Canvas component!');
1725
1725
  return store;
1726
1726
  }
1727
1727
  /**
@@ -1780,7 +1780,7 @@ function loadingFn(extensions, onProgress) {
1780
1780
  return Promise.all(input.map(input => new Promise((res, reject) => loader.load(input, data => {
1781
1781
  if (data.scene) Object.assign(data, buildGraph(data.scene));
1782
1782
  res(data);
1783
- }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1783
+ }, onProgress, error => reject(new Error(`Could not load ${input}: ${error.message})`))))));
1784
1784
  };
1785
1785
  }
1786
1786
  /**
@@ -1844,19 +1844,19 @@ const createRendererInstance = (gl, canvas) => {
1844
1844
  };
1845
1845
 
1846
1846
  const createStages = (stages, store) => {
1847
- var _stages;
1848
-
1849
1847
  const state = store.getState();
1850
1848
  let subscribers;
1851
1849
  let subscription;
1852
- stages = (_stages = stages) != null ? _stages : Lifecycle;
1853
- if (!stages.includes(Stages.Update)) throw 'The Stages.Update stage is required for R3F.';
1854
- if (!stages.includes(Stages.Render)) throw 'The Stages.Render stage is required for R3F.';
1850
+
1851
+ const _stages = stages != null ? stages : Lifecycle;
1852
+
1853
+ if (!_stages.includes(Stages.Update)) throw 'The Stages.Update stage is required for R3F.';
1854
+ if (!_stages.includes(Stages.Render)) throw 'The Stages.Render stage is required for R3F.';
1855
1855
  state.set(({
1856
1856
  internal
1857
1857
  }) => ({
1858
1858
  internal: { ...internal,
1859
- stages: stages
1859
+ stages: _stages
1860
1860
  }
1861
1861
  })); // Add useFrame loop to update stage
1862
1862
 
@@ -1880,11 +1880,43 @@ const createStages = (stages, store) => {
1880
1880
  Stages.Render.add(renderCallback, store);
1881
1881
  };
1882
1882
 
1883
+ function isCanvas(maybeCanvas) {
1884
+ return maybeCanvas instanceof HTMLCanvasElement;
1885
+ }
1886
+
1887
+ function computeInitialSize(canvas, defaultSize) {
1888
+ if (defaultSize) {
1889
+ return defaultSize;
1890
+ }
1891
+
1892
+ if (isCanvas(canvas) && canvas.parentElement) {
1893
+ const {
1894
+ width,
1895
+ height,
1896
+ top,
1897
+ left
1898
+ } = canvas.parentElement.getBoundingClientRect();
1899
+ return {
1900
+ width,
1901
+ height,
1902
+ top,
1903
+ left
1904
+ };
1905
+ }
1906
+
1907
+ return {
1908
+ width: 0,
1909
+ height: 0,
1910
+ top: 0,
1911
+ left: 0
1912
+ };
1913
+ }
1914
+
1883
1915
  function createRoot(canvas) {
1884
1916
  // Check against mistaken use of createRoot
1885
- let prevRoot = roots.get(canvas);
1886
- let prevFiber = prevRoot == null ? void 0 : prevRoot.fiber;
1887
- let prevStore = prevRoot == null ? void 0 : prevRoot.store;
1917
+ const prevRoot = roots.get(canvas);
1918
+ const prevFiber = prevRoot == null ? void 0 : prevRoot.fiber;
1919
+ const prevStore = prevRoot == null ? void 0 : prevRoot.store;
1888
1920
  if (prevRoot) console.warn('R3F.createRoot should only be called once!'); // Report when an error was detected in a previous render
1889
1921
  // https://github.com/pmndrs/react-three-fiber/pull/2261
1890
1922
 
@@ -1908,7 +1940,7 @@ function createRoot(canvas) {
1908
1940
  configure(props = {}) {
1909
1941
  let {
1910
1942
  gl: glConfig,
1911
- size,
1943
+ size: propsSize,
1912
1944
  events,
1913
1945
  onCreated: onCreatedCallback,
1914
1946
  shadows = false,
@@ -2038,17 +2070,7 @@ function createRoot(canvas) {
2038
2070
 
2039
2071
  if (dpr && state.viewport.dpr !== calculateDpr(dpr)) state.setDpr(dpr); // Check size, allow it to take on container bounds initially
2040
2072
 
2041
- size = size || (canvas.parentElement ? {
2042
- width: canvas.parentElement.clientWidth,
2043
- height: canvas.parentElement.clientHeight,
2044
- top: canvas.parentElement.clientTop,
2045
- left: canvas.parentElement.clientLeft
2046
- } : {
2047
- width: 0,
2048
- height: 0,
2049
- top: 0,
2050
- left: 0
2051
- });
2073
+ const size = computeInitialSize(canvas, propsSize);
2052
2074
 
2053
2075
  if (!is.equ(size, state.size, shallowLoose)) {
2054
2076
  state.setSize(size.width, size.height, size.updateStyle, size.top, size.left);
@@ -2065,9 +2087,9 @@ function createRoot(canvas) {
2065
2087
  performance: { ...state.performance,
2066
2088
  ...performance
2067
2089
  }
2068
- })); // Create update stages.
2090
+ })); // Create update stages. Only do this once on init
2069
2091
 
2070
- if (stages !== state.internal.stages) createStages(stages, store); // Set locals
2092
+ if (state.internal.stages.length === 0) createStages(stages, store); // Set locals
2071
2093
 
2072
2094
  onCreated = onCreatedCallback;
2073
2095
  configured = true;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-b3be5a63.cjs.dev.js');
5
+ var index = require('./index-65e750e4.cjs.dev.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-b12f488b.cjs.prod.js');
5
+ var index = require('./index-2e1b7052.cjs.prod.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -1,5 +1,5 @@
1
- import { c as createEvents, e as extend, u as useMutableCallback, a as createRoot, E as ErrorBoundary, B as Block, b as useIsomorphicLayoutEffect, d as unmountComponentAtNode } from './index-e27d4a05.esm.js';
2
- export { F as FixedStage, t as ReactThreeFiber, S as Stage, f as Stages, v as _roots, s as act, o as addAfterEffect, n as addEffect, p as addTail, m as advance, j as applyProps, g as context, c as createEvents, h as createPortal, a as createRoot, k as dispose, e as extend, q as getRootState, l as invalidate, i as reconciler, r as render, d as unmountComponentAtNode, y as useFrame, A as useGraph, C as useLoader, w as useStore, x as useThree, z as useUpdate } from './index-e27d4a05.esm.js';
1
+ import { c as createEvents, e as extend, u as useMutableCallback, a as createRoot, E as ErrorBoundary, B as Block, b as useIsomorphicLayoutEffect, d as unmountComponentAtNode } from './index-a9c7a6cd.esm.js';
2
+ export { F as FixedStage, t as ReactThreeFiber, S as Stage, f as Stages, v as _roots, s as act, o as addAfterEffect, n as addEffect, p as addTail, m as advance, j as applyProps, g as context, c as createEvents, h as createPortal, a as createRoot, k as dispose, e as extend, q as getRootState, l as invalidate, i as reconciler, r as render, d as unmountComponentAtNode, y as useFrame, A as useGraph, C as useLoader, w as useStore, x as useThree, z as useUpdate } from './index-a9c7a6cd.esm.js';
3
3
  import _extends from '@babel/runtime/helpers/esm/extends';
4
4
  import * as React from 'react';
5
5
  import * as THREE from 'three';
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('../../dist/index-b3be5a63.cjs.dev.js');
5
+ var index = require('../../dist/index-65e750e4.cjs.dev.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -39,6 +39,8 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
39
39
  var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
40
40
  var Pressability__default = /*#__PURE__*/_interopDefault(Pressability);
41
41
 
42
+ /* eslint-enable import/default, import/no-named-as-default, import/no-named-as-default-member */
43
+
42
44
  const EVENTS = {
43
45
  PRESS: 'onPress',
44
46
  PRESSIN: 'onPressIn',
@@ -144,7 +146,7 @@ function getAsset(input) {
144
146
  return expAsset.fromModule(input);
145
147
 
146
148
  default:
147
- throw 'Invalid asset! Must be a URI or module.';
149
+ throw new Error('R3F: Invalid asset! Must be a URI or module.');
148
150
  }
149
151
  }
150
152
 
@@ -273,7 +275,7 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(({
273
275
  React__namespace.useImperativeHandle(forwardedRef, () => viewRef.current);
274
276
  const handlePointerMissed = index.useMutableCallback(onPointerMissed);
275
277
  const [block, setBlock] = React__namespace.useState(false);
276
- const [error, setError] = React__namespace.useState(false); // Suspend this component if block is a promise (2nd run)
278
+ const [error, setError] = React__namespace.useState(undefined); // Suspend this component if block is a promise (2nd run)
277
279
 
278
280
  if (block) throw block; // Throw exception outwards if anything within canvas throws
279
281
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('../../dist/index-b12f488b.cjs.prod.js');
5
+ var index = require('../../dist/index-2e1b7052.cjs.prod.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -39,6 +39,8 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
39
39
  var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
40
40
  var Pressability__default = /*#__PURE__*/_interopDefault(Pressability);
41
41
 
42
+ /* eslint-enable import/default, import/no-named-as-default, import/no-named-as-default-member */
43
+
42
44
  const EVENTS = {
43
45
  PRESS: 'onPress',
44
46
  PRESSIN: 'onPressIn',
@@ -144,7 +146,7 @@ function getAsset(input) {
144
146
  return expAsset.fromModule(input);
145
147
 
146
148
  default:
147
- throw 'Invalid asset! Must be a URI or module.';
149
+ throw new Error('R3F: Invalid asset! Must be a URI or module.');
148
150
  }
149
151
  }
150
152
 
@@ -273,7 +275,7 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(({
273
275
  React__namespace.useImperativeHandle(forwardedRef, () => viewRef.current);
274
276
  const handlePointerMissed = index.useMutableCallback(onPointerMissed);
275
277
  const [block, setBlock] = React__namespace.useState(false);
276
- const [error, setError] = React__namespace.useState(false); // Suspend this component if block is a promise (2nd run)
278
+ const [error, setError] = React__namespace.useState(undefined); // Suspend this component if block is a promise (2nd run)
277
279
 
278
280
  if (block) throw block; // Throw exception outwards if anything within canvas throws
279
281
 
@@ -1,5 +1,5 @@
1
- import { c as createEvents, e as extend, u as useMutableCallback, a as createRoot, E as ErrorBoundary, B as Block, d as unmountComponentAtNode } from '../../dist/index-e27d4a05.esm.js';
2
- export { t as ReactThreeFiber, v as _roots, s as act, o as addAfterEffect, n as addEffect, p as addTail, m as advance, j as applyProps, g as context, h as createPortal, a as createRoot, k as dispose, e as extend, q as getRootState, l as invalidate, i as reconciler, r as render, d as unmountComponentAtNode, y as useFrame, A as useGraph, C as useLoader, w as useStore, x as useThree, z as useUpdate } from '../../dist/index-e27d4a05.esm.js';
1
+ import { c as createEvents, e as extend, u as useMutableCallback, a as createRoot, E as ErrorBoundary, B as Block, d as unmountComponentAtNode } from '../../dist/index-a9c7a6cd.esm.js';
2
+ export { t as ReactThreeFiber, v as _roots, s as act, o as addAfterEffect, n as addEffect, p as addTail, m as advance, j as applyProps, g as context, h as createPortal, a as createRoot, k as dispose, e as extend, q as getRootState, l as invalidate, i as reconciler, r as render, d as unmountComponentAtNode, y as useFrame, A as useGraph, C as useLoader, w as useStore, x as useThree, z as useUpdate } from '../../dist/index-a9c7a6cd.esm.js';
3
3
  import _extends from '@babel/runtime/helpers/esm/extends';
4
4
  import * as React from 'react';
5
5
  import * as THREE from 'three';
@@ -12,6 +12,8 @@ import 'react-reconciler';
12
12
  import 'scheduler';
13
13
  import 'suspend-react';
14
14
 
15
+ /* eslint-enable import/default, import/no-named-as-default, import/no-named-as-default-member */
16
+
15
17
  const EVENTS = {
16
18
  PRESS: 'onPress',
17
19
  PRESSIN: 'onPressIn',
@@ -117,7 +119,7 @@ function getAsset(input) {
117
119
  return expAsset.fromModule(input);
118
120
 
119
121
  default:
120
- throw 'Invalid asset! Must be a URI or module.';
122
+ throw new Error('R3F: Invalid asset! Must be a URI or module.');
121
123
  }
122
124
  }
123
125
 
@@ -246,7 +248,7 @@ const Canvas = /*#__PURE__*/React.forwardRef(({
246
248
  React.useImperativeHandle(forwardedRef, () => viewRef.current);
247
249
  const handlePointerMissed = useMutableCallback(onPointerMissed);
248
250
  const [block, setBlock] = React.useState(false);
249
- const [error, setError] = React.useState(false); // Suspend this component if block is a promise (2nd run)
251
+ const [error, setError] = React.useState(undefined); // Suspend this component if block is a promise (2nd run)
250
252
 
251
253
  if (block) throw block; // Throw exception outwards if anything within canvas throws
252
254
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/fiber",
3
- "version": "9.0.0-alpha.0",
3
+ "version": "9.0.0-alpha.1",
4
4
  "description": "A React renderer for Threejs",
5
5
  "keywords": [
6
6
  "react",