@react-three/fiber 9.0.0-rc.6 → 9.0.0-rc.8

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.
@@ -25,7 +25,6 @@ type ArgsProp<P> = P extends ConstructorRepresentation ? IsAllOptional<Construct
25
25
  };
26
26
  export type InstanceProps<T = any, P = any> = ArgsProp<P> & {
27
27
  object?: T;
28
- visible?: boolean;
29
28
  dispose?: null;
30
29
  attach?: AttachType<T>;
31
30
  onUpdate?: (self: T) => void;
@@ -45,7 +44,6 @@ export interface Instance<O = any> {
45
44
  previousAttach?: any;
46
45
  isHidden: boolean;
47
46
  }
48
- export declare const catalogue: Catalogue;
49
47
  export declare function extend<T extends ConstructorRepresentation>(objects: T): React.ExoticComponent<ThreeElement<T>>;
50
48
  export declare function extend<T extends Catalogue>(objects: T): void;
51
49
  export declare const reconciler: Reconciler.Reconciler<RootStore, Instance<any>, void, Instance<any>, any>;
@@ -33,8 +33,12 @@ export interface ReactProps<P> {
33
33
  export type ElementProps<T extends ConstructorRepresentation, P = InstanceType<T>> = Partial<Overwrite<P, MathProps<P> & ReactProps<P> & EventProps<P>>>;
34
34
  export type ThreeElement<T extends ConstructorRepresentation> = Mutable<Overwrite<ElementProps<T>, Omit<InstanceProps<InstanceType<T>, T>, 'object'>>>;
35
35
  type ThreeExports = typeof THREE;
36
+ type DuplicateKeys<T, U> = Extract<keyof T, keyof U>;
37
+ type Conflicts = DuplicateKeys<JSX.IntrinsicElements, {
38
+ [K in keyof ThreeExports as Uncapitalize<K>]: any;
39
+ }>;
36
40
  type ThreeElementsImpl = {
37
- [K in keyof ThreeExports as Uncapitalize<K>]: ThreeExports[K] extends ConstructorRepresentation ? ThreeElement<ThreeExports[K]> : never;
41
+ [K in keyof ThreeExports as Uncapitalize<K> extends Conflicts ? `three${Capitalize<K>}` : Uncapitalize<K>]: ThreeExports[K] extends ConstructorRepresentation ? ThreeElement<ThreeExports[K]> : never;
38
42
  };
39
43
  export interface ThreeElements extends ThreeElementsImpl {
40
44
  primitive: Omit<ThreeElement<any>, 'args'> & {
@@ -354,6 +354,7 @@ function applyProps(object, props) {
354
354
  if (instance && EVENT_REGEX.test(prop)) {
355
355
  if (typeof value === 'function') instance.handlers[prop] = value;else delete instance.handlers[prop];
356
356
  instance.eventCount = Object.keys(instance.handlers).length;
357
+ continue;
357
358
  }
358
359
 
359
360
  // Ignore setting undefined props
@@ -365,29 +366,23 @@ function applyProps(object, props) {
365
366
  target
366
367
  } = resolve(object, prop);
367
368
 
368
- // Copy if properties match signatures
369
- if (target != null && target.copy && value != null && value.constructor && target.constructor === value.constructor) {
370
- // fetch the default state of the target
371
- const ctor = getMemoizedPrototype(root);
372
- // The target key was originally null or undefined, which indicates that the object which
373
- // is now present was externally set by the user, we should therefore assign the value directly
374
- if (!is.und(ctor) && (is.und(ctor[key]) || is.nul(ctor[key]))) root[key] = value;
375
- // Otherwise copy is correct
376
- else target.copy(value);
377
- }
378
- // Layers have no copy function, we must therefore copy the mask property
379
- else if (target instanceof THREE.Layers && value instanceof THREE.Layers) {
369
+ // Layers must be written to the mask property
370
+ if (target instanceof THREE.Layers && value instanceof THREE.Layers) {
380
371
  target.mask = value.mask;
381
372
  }
373
+ // Copy if properties match signatures and implement math interface (likely read-only)
374
+ else if (target && typeof target.set === 'function' && typeof target.copy === 'function' && value != null && value.constructor && target.constructor === value.constructor) {
375
+ target.copy(value);
376
+ }
382
377
  // Set array types
383
- else if (target != null && target.set && Array.isArray(value)) {
384
- if (target.fromArray) target.fromArray(value);else target.set(...value);
378
+ else if (target && typeof target.set === 'function' && Array.isArray(value)) {
379
+ if (typeof target.fromArray === 'function') target.fromArray(value);else target.set(...value);
385
380
  }
386
381
  // Set literal types
387
- else if (target != null && target.set && typeof value !== 'object') {
388
- const isColor = target == null ? void 0 : target.isColor;
389
- // Allow setting array scalars
390
- if (!isColor && target.setScalar && typeof value === 'number') target.setScalar(value);
382
+ else if (target && typeof target.set === 'function' && typeof value === 'number') {
383
+ // Allow setting array scalars (don't call setScalar for Color since it skips conversions)
384
+ const isColor = target.isColor;
385
+ if (!isColor && typeof target.setScalar === 'function') target.setScalar(value);
391
386
  // Otherwise just set single value
392
387
  else target.set(value);
393
388
  }
@@ -594,7 +589,19 @@ function createEvents(store) {
594
589
  stopped: false
595
590
  };
596
591
  for (const hit of intersections) {
597
- const state = getRootState(hit.object);
592
+ let state = getRootState(hit.object);
593
+
594
+ // If the object is not managed by R3F, it might be parented to an element which is.
595
+ // Traverse upwards until we find a managed parent and use its state instead.
596
+ if (!state) {
597
+ hit.object.traverseAncestors(obj => {
598
+ const parentState = getRootState(obj);
599
+ if (parentState) {
600
+ state = parentState;
601
+ return false;
602
+ }
603
+ });
604
+ }
598
605
  if (state) {
599
606
  const {
600
607
  raycaster,
@@ -1230,6 +1237,8 @@ const NoEventPriority = 0;
1230
1237
  // https://github.com/microsoft/TypeScript/issues/37079
1231
1238
 
1232
1239
  const catalogue = {};
1240
+ const PREFIX_REGEX = /^three(?=[A-Z])/;
1241
+ const toPascalCase = type => `${type[0].toUpperCase()}${type.slice(1)}`;
1233
1242
  let i = 0;
1234
1243
  const isConstructor = object => typeof object === 'function';
1235
1244
  function extend(objects) {
@@ -1257,6 +1266,8 @@ function validateInstance(type, props) {
1257
1266
  }
1258
1267
  function createInstance(type, props, root) {
1259
1268
  var _props$object;
1269
+ // Remove three* prefix from elements
1270
+ type = type.replace(PREFIX_REGEX, '');
1260
1271
  validateInstance(type, props);
1261
1272
 
1262
1273
  // Regenerate the R3F instance for primitives to simulate a new object
@@ -1300,8 +1311,7 @@ function handleContainerEffects(parent, child, beforeChild) {
1300
1311
  if (!child.object) {
1301
1312
  var _child$props$object, _child$props$args;
1302
1313
  // Get target from catalogue
1303
- const name = `${child.type[0].toUpperCase()}${child.type.slice(1)}`;
1304
- const target = catalogue[name];
1314
+ const target = catalogue[toPascalCase(child.type)];
1305
1315
 
1306
1316
  // Create object
1307
1317
  child.object = (_child$props$object = child.props.object) != null ? _child$props$object : new target(...((_child$props$args = child.props.args) != null ? _child$props$args : []));
@@ -1467,8 +1477,7 @@ function swapInstances() {
1467
1477
  if (parent) {
1468
1478
  var _instance$props$objec, _instance$props$args;
1469
1479
  // Get target from catalogue
1470
- const name = `${instance.type[0].toUpperCase()}${instance.type.slice(1)}`;
1471
- const target = catalogue[name];
1480
+ const target = catalogue[toPascalCase(instance.type)];
1472
1481
 
1473
1482
  // Create object
1474
1483
  instance.object = (_instance$props$objec = instance.props.object) != null ? _instance$props$objec : new target(...((_instance$props$args = instance.props.args) != null ? _instance$props$args : []));
@@ -1637,20 +1646,6 @@ const shallowLoose = {
1637
1646
  objects: 'shallow',
1638
1647
  strict: false
1639
1648
  };
1640
- async function createRendererInstance(gl, canvas) {
1641
- const defaultProps = {
1642
- canvas: canvas,
1643
- powerPreference: 'high-performance',
1644
- antialias: true,
1645
- alpha: true
1646
- };
1647
- const customRenderer = typeof gl === 'function' ? await gl(defaultProps) : gl;
1648
- if (isRenderer(customRenderer)) return customRenderer;
1649
- return new THREE.WebGLRenderer({
1650
- ...defaultProps,
1651
- ...gl
1652
- });
1653
- }
1654
1649
  function computeInitialSize(canvas, size) {
1655
1650
  if (!size && typeof HTMLCanvasElement !== 'undefined' && canvas instanceof HTMLCanvasElement && canvas.parentElement) {
1656
1651
  const {
@@ -1728,10 +1723,13 @@ function createRoot(canvas) {
1728
1723
 
1729
1724
  // Locals
1730
1725
  let onCreated;
1731
- let configured = false;
1732
1726
  let lastCamera;
1727
+ let configured = false;
1728
+ let pending = null;
1733
1729
  return {
1734
1730
  async configure(props = {}) {
1731
+ let resolve;
1732
+ pending = new Promise(_resolve => resolve = _resolve);
1735
1733
  let {
1736
1734
  gl: glConfig,
1737
1735
  size: propsSize,
@@ -1754,9 +1752,26 @@ function createRoot(canvas) {
1754
1752
 
1755
1753
  // Set up renderer (one time only!)
1756
1754
  let gl = state.gl;
1757
- if (!state.gl) state.set({
1758
- gl: gl = await createRendererInstance(glConfig, canvas)
1759
- });
1755
+ if (!state.gl) {
1756
+ const defaultProps = {
1757
+ canvas: canvas,
1758
+ powerPreference: 'high-performance',
1759
+ antialias: true,
1760
+ alpha: true
1761
+ };
1762
+ const customRenderer = typeof glConfig === 'function' ? await glConfig(defaultProps) : glConfig;
1763
+ if (isRenderer(customRenderer)) {
1764
+ gl = customRenderer;
1765
+ } else {
1766
+ gl = new THREE.WebGLRenderer({
1767
+ ...defaultProps,
1768
+ ...glConfig
1769
+ });
1770
+ }
1771
+ state.set({
1772
+ gl
1773
+ });
1774
+ }
1760
1775
 
1761
1776
  // Set up raycaster (one time only!)
1762
1777
  let raycaster = state.raycaster;
@@ -1935,17 +1950,20 @@ function createRoot(canvas) {
1935
1950
  // Set locals
1936
1951
  onCreated = onCreatedCallback;
1937
1952
  configured = true;
1953
+ resolve();
1938
1954
  return this;
1939
1955
  },
1940
1956
  render(children) {
1941
1957
  // The root has to be configured before it can be rendered
1942
- if (!configured) throw "The root has to be configured before it can be rendered, call 'configure' first!";
1943
- reconciler.updateContainer( /*#__PURE__*/jsx(Provider, {
1944
- store: store,
1945
- children: children,
1946
- onCreated: onCreated,
1947
- rootElement: canvas
1948
- }), fiber, null, () => undefined);
1958
+ if (!configured && !pending) this.configure();
1959
+ pending.then(() => {
1960
+ reconciler.updateContainer( /*#__PURE__*/jsx(Provider, {
1961
+ store: store,
1962
+ children: children,
1963
+ onCreated: onCreated,
1964
+ rootElement: canvas
1965
+ }), fiber, null, () => undefined);
1966
+ });
1949
1967
  return store;
1950
1968
  },
1951
1969
  unmount() {
@@ -380,6 +380,7 @@ function applyProps(object, props) {
380
380
  if (instance && EVENT_REGEX.test(prop)) {
381
381
  if (typeof value === 'function') instance.handlers[prop] = value;else delete instance.handlers[prop];
382
382
  instance.eventCount = Object.keys(instance.handlers).length;
383
+ continue;
383
384
  }
384
385
 
385
386
  // Ignore setting undefined props
@@ -391,29 +392,23 @@ function applyProps(object, props) {
391
392
  target
392
393
  } = resolve(object, prop);
393
394
 
394
- // Copy if properties match signatures
395
- if (target != null && target.copy && value != null && value.constructor && target.constructor === value.constructor) {
396
- // fetch the default state of the target
397
- const ctor = getMemoizedPrototype(root);
398
- // The target key was originally null or undefined, which indicates that the object which
399
- // is now present was externally set by the user, we should therefore assign the value directly
400
- if (!is.und(ctor) && (is.und(ctor[key]) || is.nul(ctor[key]))) root[key] = value;
401
- // Otherwise copy is correct
402
- else target.copy(value);
403
- }
404
- // Layers have no copy function, we must therefore copy the mask property
405
- else if (target instanceof THREE__namespace.Layers && value instanceof THREE__namespace.Layers) {
395
+ // Layers must be written to the mask property
396
+ if (target instanceof THREE__namespace.Layers && value instanceof THREE__namespace.Layers) {
406
397
  target.mask = value.mask;
407
398
  }
399
+ // Copy if properties match signatures and implement math interface (likely read-only)
400
+ else if (target && typeof target.set === 'function' && typeof target.copy === 'function' && value != null && value.constructor && target.constructor === value.constructor) {
401
+ target.copy(value);
402
+ }
408
403
  // Set array types
409
- else if (target != null && target.set && Array.isArray(value)) {
410
- if (target.fromArray) target.fromArray(value);else target.set(...value);
404
+ else if (target && typeof target.set === 'function' && Array.isArray(value)) {
405
+ if (typeof target.fromArray === 'function') target.fromArray(value);else target.set(...value);
411
406
  }
412
407
  // Set literal types
413
- else if (target != null && target.set && typeof value !== 'object') {
414
- const isColor = target == null ? void 0 : target.isColor;
415
- // Allow setting array scalars
416
- if (!isColor && target.setScalar && typeof value === 'number') target.setScalar(value);
408
+ else if (target && typeof target.set === 'function' && typeof value === 'number') {
409
+ // Allow setting array scalars (don't call setScalar for Color since it skips conversions)
410
+ const isColor = target.isColor;
411
+ if (!isColor && typeof target.setScalar === 'function') target.setScalar(value);
417
412
  // Otherwise just set single value
418
413
  else target.set(value);
419
414
  }
@@ -620,7 +615,19 @@ function createEvents(store) {
620
615
  stopped: false
621
616
  };
622
617
  for (const hit of intersections) {
623
- const state = getRootState(hit.object);
618
+ let state = getRootState(hit.object);
619
+
620
+ // If the object is not managed by R3F, it might be parented to an element which is.
621
+ // Traverse upwards until we find a managed parent and use its state instead.
622
+ if (!state) {
623
+ hit.object.traverseAncestors(obj => {
624
+ const parentState = getRootState(obj);
625
+ if (parentState) {
626
+ state = parentState;
627
+ return false;
628
+ }
629
+ });
630
+ }
624
631
  if (state) {
625
632
  const {
626
633
  raycaster,
@@ -1256,6 +1263,8 @@ const NoEventPriority = 0;
1256
1263
  // https://github.com/microsoft/TypeScript/issues/37079
1257
1264
 
1258
1265
  const catalogue = {};
1266
+ const PREFIX_REGEX = /^three(?=[A-Z])/;
1267
+ const toPascalCase = type => `${type[0].toUpperCase()}${type.slice(1)}`;
1259
1268
  let i = 0;
1260
1269
  const isConstructor = object => typeof object === 'function';
1261
1270
  function extend(objects) {
@@ -1283,6 +1292,8 @@ function validateInstance(type, props) {
1283
1292
  }
1284
1293
  function createInstance(type, props, root) {
1285
1294
  var _props$object;
1295
+ // Remove three* prefix from elements
1296
+ type = type.replace(PREFIX_REGEX, '');
1286
1297
  validateInstance(type, props);
1287
1298
 
1288
1299
  // Regenerate the R3F instance for primitives to simulate a new object
@@ -1326,8 +1337,7 @@ function handleContainerEffects(parent, child, beforeChild) {
1326
1337
  if (!child.object) {
1327
1338
  var _child$props$object, _child$props$args;
1328
1339
  // Get target from catalogue
1329
- const name = `${child.type[0].toUpperCase()}${child.type.slice(1)}`;
1330
- const target = catalogue[name];
1340
+ const target = catalogue[toPascalCase(child.type)];
1331
1341
 
1332
1342
  // Create object
1333
1343
  child.object = (_child$props$object = child.props.object) != null ? _child$props$object : new target(...((_child$props$args = child.props.args) != null ? _child$props$args : []));
@@ -1493,8 +1503,7 @@ function swapInstances() {
1493
1503
  if (parent) {
1494
1504
  var _instance$props$objec, _instance$props$args;
1495
1505
  // Get target from catalogue
1496
- const name = `${instance.type[0].toUpperCase()}${instance.type.slice(1)}`;
1497
- const target = catalogue[name];
1506
+ const target = catalogue[toPascalCase(instance.type)];
1498
1507
 
1499
1508
  // Create object
1500
1509
  instance.object = (_instance$props$objec = instance.props.object) != null ? _instance$props$objec : new target(...((_instance$props$args = instance.props.args) != null ? _instance$props$args : []));
@@ -1663,20 +1672,6 @@ const shallowLoose = {
1663
1672
  objects: 'shallow',
1664
1673
  strict: false
1665
1674
  };
1666
- async function createRendererInstance(gl, canvas) {
1667
- const defaultProps = {
1668
- canvas: canvas,
1669
- powerPreference: 'high-performance',
1670
- antialias: true,
1671
- alpha: true
1672
- };
1673
- const customRenderer = typeof gl === 'function' ? await gl(defaultProps) : gl;
1674
- if (isRenderer(customRenderer)) return customRenderer;
1675
- return new THREE__namespace.WebGLRenderer({
1676
- ...defaultProps,
1677
- ...gl
1678
- });
1679
- }
1680
1675
  function computeInitialSize(canvas, size) {
1681
1676
  if (!size && typeof HTMLCanvasElement !== 'undefined' && canvas instanceof HTMLCanvasElement && canvas.parentElement) {
1682
1677
  const {
@@ -1754,10 +1749,13 @@ function createRoot(canvas) {
1754
1749
 
1755
1750
  // Locals
1756
1751
  let onCreated;
1757
- let configured = false;
1758
1752
  let lastCamera;
1753
+ let configured = false;
1754
+ let pending = null;
1759
1755
  return {
1760
1756
  async configure(props = {}) {
1757
+ let resolve;
1758
+ pending = new Promise(_resolve => resolve = _resolve);
1761
1759
  let {
1762
1760
  gl: glConfig,
1763
1761
  size: propsSize,
@@ -1780,9 +1778,26 @@ function createRoot(canvas) {
1780
1778
 
1781
1779
  // Set up renderer (one time only!)
1782
1780
  let gl = state.gl;
1783
- if (!state.gl) state.set({
1784
- gl: gl = await createRendererInstance(glConfig, canvas)
1785
- });
1781
+ if (!state.gl) {
1782
+ const defaultProps = {
1783
+ canvas: canvas,
1784
+ powerPreference: 'high-performance',
1785
+ antialias: true,
1786
+ alpha: true
1787
+ };
1788
+ const customRenderer = typeof glConfig === 'function' ? await glConfig(defaultProps) : glConfig;
1789
+ if (isRenderer(customRenderer)) {
1790
+ gl = customRenderer;
1791
+ } else {
1792
+ gl = new THREE__namespace.WebGLRenderer({
1793
+ ...defaultProps,
1794
+ ...glConfig
1795
+ });
1796
+ }
1797
+ state.set({
1798
+ gl
1799
+ });
1800
+ }
1786
1801
 
1787
1802
  // Set up raycaster (one time only!)
1788
1803
  let raycaster = state.raycaster;
@@ -1961,17 +1976,20 @@ function createRoot(canvas) {
1961
1976
  // Set locals
1962
1977
  onCreated = onCreatedCallback;
1963
1978
  configured = true;
1979
+ resolve();
1964
1980
  return this;
1965
1981
  },
1966
1982
  render(children) {
1967
1983
  // The root has to be configured before it can be rendered
1968
- if (!configured) throw "The root has to be configured before it can be rendered, call 'configure' first!";
1969
- reconciler.updateContainer( /*#__PURE__*/jsxRuntime.jsx(Provider, {
1970
- store: store,
1971
- children: children,
1972
- onCreated: onCreated,
1973
- rootElement: canvas
1974
- }), fiber, null, () => undefined);
1984
+ if (!configured && !pending) this.configure();
1985
+ pending.then(() => {
1986
+ reconciler.updateContainer( /*#__PURE__*/jsxRuntime.jsx(Provider, {
1987
+ store: store,
1988
+ children: children,
1989
+ onCreated: onCreated,
1990
+ rootElement: canvas
1991
+ }), fiber, null, () => undefined);
1992
+ });
1975
1993
  return store;
1976
1994
  },
1977
1995
  unmount() {
@@ -380,6 +380,7 @@ function applyProps(object, props) {
380
380
  if (instance && EVENT_REGEX.test(prop)) {
381
381
  if (typeof value === 'function') instance.handlers[prop] = value;else delete instance.handlers[prop];
382
382
  instance.eventCount = Object.keys(instance.handlers).length;
383
+ continue;
383
384
  }
384
385
 
385
386
  // Ignore setting undefined props
@@ -391,29 +392,23 @@ function applyProps(object, props) {
391
392
  target
392
393
  } = resolve(object, prop);
393
394
 
394
- // Copy if properties match signatures
395
- if (target != null && target.copy && value != null && value.constructor && target.constructor === value.constructor) {
396
- // fetch the default state of the target
397
- const ctor = getMemoizedPrototype(root);
398
- // The target key was originally null or undefined, which indicates that the object which
399
- // is now present was externally set by the user, we should therefore assign the value directly
400
- if (!is.und(ctor) && (is.und(ctor[key]) || is.nul(ctor[key]))) root[key] = value;
401
- // Otherwise copy is correct
402
- else target.copy(value);
403
- }
404
- // Layers have no copy function, we must therefore copy the mask property
405
- else if (target instanceof THREE__namespace.Layers && value instanceof THREE__namespace.Layers) {
395
+ // Layers must be written to the mask property
396
+ if (target instanceof THREE__namespace.Layers && value instanceof THREE__namespace.Layers) {
406
397
  target.mask = value.mask;
407
398
  }
399
+ // Copy if properties match signatures and implement math interface (likely read-only)
400
+ else if (target && typeof target.set === 'function' && typeof target.copy === 'function' && value != null && value.constructor && target.constructor === value.constructor) {
401
+ target.copy(value);
402
+ }
408
403
  // Set array types
409
- else if (target != null && target.set && Array.isArray(value)) {
410
- if (target.fromArray) target.fromArray(value);else target.set(...value);
404
+ else if (target && typeof target.set === 'function' && Array.isArray(value)) {
405
+ if (typeof target.fromArray === 'function') target.fromArray(value);else target.set(...value);
411
406
  }
412
407
  // Set literal types
413
- else if (target != null && target.set && typeof value !== 'object') {
414
- const isColor = target == null ? void 0 : target.isColor;
415
- // Allow setting array scalars
416
- if (!isColor && target.setScalar && typeof value === 'number') target.setScalar(value);
408
+ else if (target && typeof target.set === 'function' && typeof value === 'number') {
409
+ // Allow setting array scalars (don't call setScalar for Color since it skips conversions)
410
+ const isColor = target.isColor;
411
+ if (!isColor && typeof target.setScalar === 'function') target.setScalar(value);
417
412
  // Otherwise just set single value
418
413
  else target.set(value);
419
414
  }
@@ -620,7 +615,19 @@ function createEvents(store) {
620
615
  stopped: false
621
616
  };
622
617
  for (const hit of intersections) {
623
- const state = getRootState(hit.object);
618
+ let state = getRootState(hit.object);
619
+
620
+ // If the object is not managed by R3F, it might be parented to an element which is.
621
+ // Traverse upwards until we find a managed parent and use its state instead.
622
+ if (!state) {
623
+ hit.object.traverseAncestors(obj => {
624
+ const parentState = getRootState(obj);
625
+ if (parentState) {
626
+ state = parentState;
627
+ return false;
628
+ }
629
+ });
630
+ }
624
631
  if (state) {
625
632
  const {
626
633
  raycaster,
@@ -1256,6 +1263,8 @@ const NoEventPriority = 0;
1256
1263
  // https://github.com/microsoft/TypeScript/issues/37079
1257
1264
 
1258
1265
  const catalogue = {};
1266
+ const PREFIX_REGEX = /^three(?=[A-Z])/;
1267
+ const toPascalCase = type => `${type[0].toUpperCase()}${type.slice(1)}`;
1259
1268
  let i = 0;
1260
1269
  const isConstructor = object => typeof object === 'function';
1261
1270
  function extend(objects) {
@@ -1283,6 +1292,8 @@ function validateInstance(type, props) {
1283
1292
  }
1284
1293
  function createInstance(type, props, root) {
1285
1294
  var _props$object;
1295
+ // Remove three* prefix from elements
1296
+ type = type.replace(PREFIX_REGEX, '');
1286
1297
  validateInstance(type, props);
1287
1298
 
1288
1299
  // Regenerate the R3F instance for primitives to simulate a new object
@@ -1326,8 +1337,7 @@ function handleContainerEffects(parent, child, beforeChild) {
1326
1337
  if (!child.object) {
1327
1338
  var _child$props$object, _child$props$args;
1328
1339
  // Get target from catalogue
1329
- const name = `${child.type[0].toUpperCase()}${child.type.slice(1)}`;
1330
- const target = catalogue[name];
1340
+ const target = catalogue[toPascalCase(child.type)];
1331
1341
 
1332
1342
  // Create object
1333
1343
  child.object = (_child$props$object = child.props.object) != null ? _child$props$object : new target(...((_child$props$args = child.props.args) != null ? _child$props$args : []));
@@ -1493,8 +1503,7 @@ function swapInstances() {
1493
1503
  if (parent) {
1494
1504
  var _instance$props$objec, _instance$props$args;
1495
1505
  // Get target from catalogue
1496
- const name = `${instance.type[0].toUpperCase()}${instance.type.slice(1)}`;
1497
- const target = catalogue[name];
1506
+ const target = catalogue[toPascalCase(instance.type)];
1498
1507
 
1499
1508
  // Create object
1500
1509
  instance.object = (_instance$props$objec = instance.props.object) != null ? _instance$props$objec : new target(...((_instance$props$args = instance.props.args) != null ? _instance$props$args : []));
@@ -1663,20 +1672,6 @@ const shallowLoose = {
1663
1672
  objects: 'shallow',
1664
1673
  strict: false
1665
1674
  };
1666
- async function createRendererInstance(gl, canvas) {
1667
- const defaultProps = {
1668
- canvas: canvas,
1669
- powerPreference: 'high-performance',
1670
- antialias: true,
1671
- alpha: true
1672
- };
1673
- const customRenderer = typeof gl === 'function' ? await gl(defaultProps) : gl;
1674
- if (isRenderer(customRenderer)) return customRenderer;
1675
- return new THREE__namespace.WebGLRenderer({
1676
- ...defaultProps,
1677
- ...gl
1678
- });
1679
- }
1680
1675
  function computeInitialSize(canvas, size) {
1681
1676
  if (!size && typeof HTMLCanvasElement !== 'undefined' && canvas instanceof HTMLCanvasElement && canvas.parentElement) {
1682
1677
  const {
@@ -1754,10 +1749,13 @@ function createRoot(canvas) {
1754
1749
 
1755
1750
  // Locals
1756
1751
  let onCreated;
1757
- let configured = false;
1758
1752
  let lastCamera;
1753
+ let configured = false;
1754
+ let pending = null;
1759
1755
  return {
1760
1756
  async configure(props = {}) {
1757
+ let resolve;
1758
+ pending = new Promise(_resolve => resolve = _resolve);
1761
1759
  let {
1762
1760
  gl: glConfig,
1763
1761
  size: propsSize,
@@ -1780,9 +1778,26 @@ function createRoot(canvas) {
1780
1778
 
1781
1779
  // Set up renderer (one time only!)
1782
1780
  let gl = state.gl;
1783
- if (!state.gl) state.set({
1784
- gl: gl = await createRendererInstance(glConfig, canvas)
1785
- });
1781
+ if (!state.gl) {
1782
+ const defaultProps = {
1783
+ canvas: canvas,
1784
+ powerPreference: 'high-performance',
1785
+ antialias: true,
1786
+ alpha: true
1787
+ };
1788
+ const customRenderer = typeof glConfig === 'function' ? await glConfig(defaultProps) : glConfig;
1789
+ if (isRenderer(customRenderer)) {
1790
+ gl = customRenderer;
1791
+ } else {
1792
+ gl = new THREE__namespace.WebGLRenderer({
1793
+ ...defaultProps,
1794
+ ...glConfig
1795
+ });
1796
+ }
1797
+ state.set({
1798
+ gl
1799
+ });
1800
+ }
1786
1801
 
1787
1802
  // Set up raycaster (one time only!)
1788
1803
  let raycaster = state.raycaster;
@@ -1961,17 +1976,20 @@ function createRoot(canvas) {
1961
1976
  // Set locals
1962
1977
  onCreated = onCreatedCallback;
1963
1978
  configured = true;
1979
+ resolve();
1964
1980
  return this;
1965
1981
  },
1966
1982
  render(children) {
1967
1983
  // The root has to be configured before it can be rendered
1968
- if (!configured) throw "The root has to be configured before it can be rendered, call 'configure' first!";
1969
- reconciler.updateContainer( /*#__PURE__*/jsxRuntime.jsx(Provider, {
1970
- store: store,
1971
- children: children,
1972
- onCreated: onCreated,
1973
- rootElement: canvas
1974
- }), fiber, null, () => undefined);
1984
+ if (!configured && !pending) this.configure();
1985
+ pending.then(() => {
1986
+ reconciler.updateContainer( /*#__PURE__*/jsxRuntime.jsx(Provider, {
1987
+ store: store,
1988
+ children: children,
1989
+ onCreated: onCreated,
1990
+ rootElement: canvas
1991
+ }), fiber, null, () => undefined);
1992
+ });
1975
1993
  return store;
1976
1994
  },
1977
1995
  unmount() {
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var events = require('./events-4464c9d4.cjs.dev.js');
5
+ var events = require('./events-89dd614d.cjs.dev.js');
6
6
  var React = require('react');
7
7
  var THREE = require('three');
8
8
  var useMeasure = require('react-use-measure');
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var events = require('./events-79ccf613.cjs.prod.js');
5
+ var events = require('./events-b4105f71.cjs.prod.js');
6
6
  var React = require('react');
7
7
  var THREE = require('three');
8
8
  var useMeasure = require('react-use-measure');
@@ -1,5 +1,5 @@
1
- import { e as extend, u as useBridge, a as useMutableCallback, b as useIsomorphicLayoutEffect, c as createRoot, i as isRef, E as ErrorBoundary, B as Block, d as unmountComponentAtNode, f as createPointerEvents } from './events-06bc1550.esm.js';
2
- export { t as ReactThreeFiber, _ as _roots, w as act, k as addAfterEffect, j as addEffect, l as addTail, n as advance, q as applyProps, x as buildGraph, p as context, g as createEvents, o as createPortal, c as createRoot, v as dispose, f as events, e as extend, h as flushGlobalEffects, s as getRootState, m as invalidate, r as reconciler, d as unmountComponentAtNode, C as useFrame, D as useGraph, y as useInstanceHandle, F as useLoader, z as useStore, A as useThree } from './events-06bc1550.esm.js';
1
+ import { e as extend, u as useBridge, a as useMutableCallback, b as useIsomorphicLayoutEffect, c as createRoot, i as isRef, E as ErrorBoundary, B as Block, d as unmountComponentAtNode, f as createPointerEvents } from './events-5b423474.esm.js';
2
+ export { t as ReactThreeFiber, _ as _roots, w as act, k as addAfterEffect, j as addEffect, l as addTail, n as advance, q as applyProps, x as buildGraph, p as context, g as createEvents, o as createPortal, c as createRoot, v as dispose, f as events, e as extend, h as flushGlobalEffects, s as getRootState, m as invalidate, r as reconciler, d as unmountComponentAtNode, C as useFrame, D as useGraph, y as useInstanceHandle, F as useLoader, z as useStore, A as useThree } from './events-5b423474.esm.js';
3
3
  import * as React from 'react';
4
4
  import * as THREE from 'three';
5
5
  import useMeasure from 'react-use-measure';
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var events = require('../../dist/events-4464c9d4.cjs.dev.js');
5
+ var events = require('../../dist/events-89dd614d.cjs.dev.js');
6
6
  var React = require('react');
7
7
  var THREE = require('three');
8
8
  var reactNative = require('react-native');
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var events = require('../../dist/events-79ccf613.cjs.prod.js');
5
+ var events = require('../../dist/events-b4105f71.cjs.prod.js');
6
6
  var React = require('react');
7
7
  var THREE = require('three');
8
8
  var reactNative = require('react-native');
@@ -1,5 +1,5 @@
1
- import { e as extend, u as useBridge, a as useMutableCallback, c as createRoot, b as useIsomorphicLayoutEffect, E as ErrorBoundary, B as Block, d as unmountComponentAtNode, f as createPointerEvents, g as createEvents } from '../../dist/events-06bc1550.esm.js';
2
- export { t as ReactThreeFiber, _ as _roots, w as act, k as addAfterEffect, j as addEffect, l as addTail, n as advance, q as applyProps, x as buildGraph, p as context, g as createEvents, o as createPortal, c as createRoot, v as dispose, e as extend, h as flushGlobalEffects, s as getRootState, m as invalidate, r as reconciler, d as unmountComponentAtNode, C as useFrame, D as useGraph, y as useInstanceHandle, F as useLoader, z as useStore, A as useThree } from '../../dist/events-06bc1550.esm.js';
1
+ import { e as extend, u as useBridge, a as useMutableCallback, c as createRoot, b as useIsomorphicLayoutEffect, E as ErrorBoundary, B as Block, d as unmountComponentAtNode, f as createPointerEvents, g as createEvents } from '../../dist/events-5b423474.esm.js';
2
+ export { t as ReactThreeFiber, _ as _roots, w as act, k as addAfterEffect, j as addEffect, l as addTail, n as advance, q as applyProps, x as buildGraph, p as context, g as createEvents, o as createPortal, c as createRoot, v as dispose, e as extend, h as flushGlobalEffects, s as getRootState, m as invalidate, r as reconciler, d as unmountComponentAtNode, C as useFrame, D as useGraph, y as useInstanceHandle, F as useLoader, z as useStore, A as useThree } from '../../dist/events-5b423474.esm.js';
3
3
  import * as React from 'react';
4
4
  import * as THREE from 'three';
5
5
  import { PanResponder, PixelRatio, StyleSheet, View, Platform, Image, NativeModules } from 'react-native';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/fiber",
3
- "version": "9.0.0-rc.6",
3
+ "version": "9.0.0-rc.8",
4
4
  "description": "A React renderer for Threejs",
5
5
  "keywords": [
6
6
  "react",