@react-three/fiber 8.15.19 → 8.16.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.
Files changed (28) hide show
  1. package/CHANGELOG.md +956 -944
  2. package/dist/declarations/src/core/events.d.ts +93 -93
  3. package/dist/declarations/src/core/hooks.d.ts +57 -57
  4. package/dist/declarations/src/core/index.d.ts +87 -87
  5. package/dist/declarations/src/core/loop.d.ts +38 -38
  6. package/dist/declarations/src/core/renderer.d.ts +58 -58
  7. package/dist/declarations/src/core/store.d.ts +138 -138
  8. package/dist/declarations/src/core/utils.d.ts +131 -131
  9. package/dist/declarations/src/index.d.ts +12 -12
  10. package/dist/declarations/src/native/Canvas.d.ts +14 -14
  11. package/dist/declarations/src/native/events.d.ts +5 -5
  12. package/dist/declarations/src/native/polyfills.d.ts +1 -1
  13. package/dist/declarations/src/native.d.ts +12 -12
  14. package/dist/declarations/src/three-types.d.ts +393 -393
  15. package/dist/declarations/src/web/Canvas.d.ts +24 -24
  16. package/dist/declarations/src/web/events.d.ts +5 -5
  17. package/dist/{index-b90e75f9.cjs.dev.js → index-382d4f47.cjs.dev.js} +92 -73
  18. package/dist/{index-e6b5343a.esm.js → index-d98fd1c7.esm.js} +92 -73
  19. package/dist/{index-87af8422.cjs.prod.js → index-e8d6e828.cjs.prod.js} +92 -73
  20. package/dist/react-three-fiber.cjs.dev.js +4 -4
  21. package/dist/react-three-fiber.cjs.prod.js +4 -4
  22. package/dist/react-three-fiber.esm.js +5 -5
  23. package/native/dist/react-three-fiber-native.cjs.dev.js +7 -7
  24. package/native/dist/react-three-fiber-native.cjs.prod.js +7 -7
  25. package/native/dist/react-three-fiber-native.esm.js +8 -8
  26. package/native/package.json +5 -5
  27. package/package.json +1 -1
  28. package/readme.md +253 -253
@@ -95,6 +95,10 @@ function createRenderer(_roots, _getEventPriority) {
95
95
  child.dispatchEvent({
96
96
  type: 'added'
97
97
  });
98
+ parentInstance.dispatchEvent({
99
+ type: 'childadded',
100
+ child
101
+ });
98
102
  const restSiblings = parentInstance.children.filter(sibling => sibling !== child);
99
103
  const index = restSiblings.indexOf(beforeChild);
100
104
  parentInstance.children = [...restSiblings.slice(0, index), child, ...restSiblings.slice(index)];
@@ -355,12 +359,12 @@ function createRenderer(_roots, _getEventPriority) {
355
359
  }
356
360
 
357
361
  var _window$document, _window$navigator;
358
- /**
359
- * Returns `true` with correct TS type inference if an object has a configurable color space (since r152).
362
+ /**
363
+ * Returns `true` with correct TS type inference if an object has a configurable color space (since r152).
360
364
  */
361
365
  const hasColorSpace = object => 'colorSpace' in object || 'outputColorSpace' in object;
362
- /**
363
- * The current THREE.ColorManagement instance, if present.
366
+ /**
367
+ * The current THREE.ColorManagement instance, if present.
364
368
  */
365
369
  const getColorManagement = () => {
366
370
  var _ColorManagement;
@@ -369,14 +373,14 @@ const getColorManagement = () => {
369
373
  const isOrthographicCamera = def => def && def.isOrthographicCamera;
370
374
  const isRef = obj => obj && obj.hasOwnProperty('current');
371
375
 
372
- /**
373
- * An SSR-friendly useLayoutEffect.
374
- *
375
- * React currently throws a warning when using useLayoutEffect on the server.
376
- * To get around it, we can conditionally useEffect on the server (no-op) and
377
- * useLayoutEffect elsewhere.
378
- *
379
- * @see https://github.com/facebook/react/issues/14927
376
+ /**
377
+ * An SSR-friendly useLayoutEffect.
378
+ *
379
+ * React currently throws a warning when using useLayoutEffect on the server.
380
+ * To get around it, we can conditionally useEffect on the server (no-op) and
381
+ * useLayoutEffect elsewhere.
382
+ *
383
+ * @see https://github.com/facebook/react/issues/14927
380
384
  */
381
385
  const useIsomorphicLayoutEffect = typeof window !== 'undefined' && ((_window$document = window.document) != null && _window$document.createElement || ((_window$navigator = window.navigator) == null ? void 0 : _window$navigator.product) === 'ReactNative') ? React.useLayoutEffect : React.useEffect;
382
386
  function useMutableCallback(fn) {
@@ -421,16 +425,16 @@ function calculateDpr(dpr) {
421
425
  return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
422
426
  }
423
427
 
424
- /**
425
- * Returns instance root state
428
+ /**
429
+ * Returns instance root state
426
430
  */
427
431
  const getRootState = obj => {
428
432
  var _r3f;
429
433
  return (_r3f = obj.__r3f) == null ? void 0 : _r3f.root.getState();
430
434
  };
431
435
 
432
- /**
433
- * Returns the instances initial (outmost) root
436
+ /**
437
+ * Returns the instances initial (outmost) root
434
438
  */
435
439
  function findInitialRoot(child) {
436
440
  let root = child.__r3f.root;
@@ -487,8 +491,8 @@ const is = {
487
491
  }
488
492
  };
489
493
 
490
- /**
491
- * Collects nodes and materials from a THREE.Object3D.
494
+ /**
495
+ * Collects nodes and materials from a THREE.Object3D.
492
496
  */
493
497
  function buildGraph(object) {
494
498
  const data = {
@@ -830,9 +834,9 @@ function getEventPriority() {
830
834
  }
831
835
  }
832
836
 
833
- /**
834
- * Release pointer captures.
835
- * This is called by releasePointerCapture in the API, and when an object is removed.
837
+ /**
838
+ * Release pointer captures.
839
+ * This is called by releasePointerCapture in the API, and when an object is removed.
836
840
  */
837
841
  function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
838
842
  const captureData = captures.get(obj);
@@ -1167,19 +1171,19 @@ function createEvents(store) {
1167
1171
  // Check presence of handlers
1168
1172
  if (!(instance != null && instance.eventCount)) return;
1169
1173
 
1170
- /*
1171
- MAYBE TODO, DELETE IF NOT:
1172
- Check if the object is captured, captured events should not have intersects running in parallel
1173
- But wouldn't it be better to just replace capturedMap with a single entry?
1174
- Also, are we OK with straight up making picking up multiple objects impossible?
1175
-
1176
- const pointerId = (data as ThreeEvent<PointerEvent>).pointerId
1177
- if (pointerId !== undefined) {
1178
- const capturedMeshSet = internal.capturedMap.get(pointerId)
1179
- if (capturedMeshSet) {
1180
- const captured = capturedMeshSet.get(eventObject)
1181
- if (captured && captured.localState.stopped) return
1182
- }
1174
+ /*
1175
+ MAYBE TODO, DELETE IF NOT:
1176
+ Check if the object is captured, captured events should not have intersects running in parallel
1177
+ But wouldn't it be better to just replace capturedMap with a single entry?
1178
+ Also, are we OK with straight up making picking up multiple objects impossible?
1179
+
1180
+ const pointerId = (data as ThreeEvent<PointerEvent>).pointerId
1181
+ if (pointerId !== undefined) {
1182
+ const capturedMeshSet = internal.capturedMap.get(pointerId)
1183
+ if (capturedMeshSet) {
1184
+ const captured = capturedMeshSet.get(eventObject)
1185
+ if (captured && captured.localState.stopped) return
1186
+ }
1183
1187
  }*/
1184
1188
 
1185
1189
  if (isPointerMove) {
@@ -1485,21 +1489,21 @@ let globalEffects = new Set();
1485
1489
  let globalAfterEffects = new Set();
1486
1490
  let globalTailEffects = new Set();
1487
1491
 
1488
- /**
1489
- * Adds a global render callback which is called each frame.
1490
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
1492
+ /**
1493
+ * Adds a global render callback which is called each frame.
1494
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
1491
1495
  */
1492
1496
  const addEffect = callback => createSubs(callback, globalEffects);
1493
1497
 
1494
- /**
1495
- * Adds a global after-render callback which is called each frame.
1496
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
1498
+ /**
1499
+ * Adds a global after-render callback which is called each frame.
1500
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
1497
1501
  */
1498
1502
  const addAfterEffect = callback => createSubs(callback, globalAfterEffects);
1499
1503
 
1500
- /**
1501
- * Adds a global callback which is called when rendering stops.
1502
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
1504
+ /**
1505
+ * Adds a global callback which is called when rendering stops.
1506
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
1503
1507
  */
1504
1508
  const addTail = callback => createSubs(callback, globalTailEffects);
1505
1509
  function run(effects, timestamp) {
@@ -1545,6 +1549,7 @@ function render$1(timestamp, state, frame) {
1545
1549
  }
1546
1550
  function createLoop(roots) {
1547
1551
  let running = false;
1552
+ let useFrameInProgress = false;
1548
1553
  let repeat;
1549
1554
  let frame;
1550
1555
  let state;
@@ -1557,6 +1562,7 @@ function createLoop(roots) {
1557
1562
  flushGlobalEffects('before', timestamp);
1558
1563
 
1559
1564
  // Render all roots
1565
+ useFrameInProgress = true;
1560
1566
  for (const root of roots.values()) {
1561
1567
  var _state$gl$xr;
1562
1568
  state = root.store.getState();
@@ -1565,6 +1571,7 @@ function createLoop(roots) {
1565
1571
  repeat += render$1(timestamp, state);
1566
1572
  }
1567
1573
  }
1574
+ useFrameInProgress = false;
1568
1575
 
1569
1576
  // Run after-effects
1570
1577
  flushGlobalEffects('after', timestamp);
@@ -1583,8 +1590,20 @@ function createLoop(roots) {
1583
1590
  var _state$gl$xr2;
1584
1591
  if (!state) return roots.forEach(root => invalidate(root.store.getState(), frames));
1585
1592
  if ((_state$gl$xr2 = state.gl.xr) != null && _state$gl$xr2.isPresenting || !state.internal.active || state.frameloop === 'never') return;
1586
- // Increase frames, do not go higher than 60
1587
- state.internal.frames = Math.min(60, state.internal.frames + frames);
1593
+ if (frames > 1) {
1594
+ // legacy support for people using frames parameters
1595
+ // Increase frames, do not go higher than 60
1596
+ state.internal.frames = Math.min(60, state.internal.frames + frames);
1597
+ } else {
1598
+ if (useFrameInProgress) {
1599
+ //called from within a useFrame, it means the user wants an additional frame
1600
+ state.internal.frames = 2;
1601
+ } else {
1602
+ //the user need a new frame, no need to increment further than 1
1603
+ state.internal.frames = 1;
1604
+ }
1605
+ }
1606
+
1588
1607
  // If the render-loop isn't active, start it
1589
1608
  if (!running) {
1590
1609
  running = true;
@@ -1603,11 +1622,11 @@ function createLoop(roots) {
1603
1622
  };
1604
1623
  }
1605
1624
 
1606
- /**
1607
- * Exposes an object's {@link LocalState}.
1608
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useInstanceHandle
1609
- *
1610
- * **Note**: this is an escape hatch to react-internal fields. Expect this to change significantly between versions.
1625
+ /**
1626
+ * Exposes an object's {@link LocalState}.
1627
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useInstanceHandle
1628
+ *
1629
+ * **Note**: this is an escape hatch to react-internal fields. Expect this to change significantly between versions.
1611
1630
  */
1612
1631
  function useInstanceHandle(ref) {
1613
1632
  const instance = React.useRef(null);
@@ -1620,18 +1639,18 @@ function useStore() {
1620
1639
  return store;
1621
1640
  }
1622
1641
 
1623
- /**
1624
- * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1625
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1642
+ /**
1643
+ * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1644
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1626
1645
  */
1627
1646
  function useThree(selector = state => state, equalityFn) {
1628
1647
  return useStore()(selector, equalityFn);
1629
1648
  }
1630
1649
 
1631
- /**
1632
- * Executes a callback before render in a shared frame loop.
1633
- * Can order effects with render priority or manually render with a positive priority.
1634
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1650
+ /**
1651
+ * Executes a callback before render in a shared frame loop.
1652
+ * Can order effects with render priority or manually render with a positive priority.
1653
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1635
1654
  */
1636
1655
  function useFrame(callback, renderPriority = 0) {
1637
1656
  const store = useStore();
@@ -1643,9 +1662,9 @@ function useFrame(callback, renderPriority = 0) {
1643
1662
  return null;
1644
1663
  }
1645
1664
 
1646
- /**
1647
- * Returns a node graph of an object with named nodes & materials.
1648
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1665
+ /**
1666
+ * Returns a node graph of an object with named nodes & materials.
1667
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1649
1668
  */
1650
1669
  function useGraph(object) {
1651
1670
  return React.useMemo(() => buildGraph(object), [object]);
@@ -1667,11 +1686,11 @@ function loadingFn(extensions, onProgress) {
1667
1686
  }, onProgress, error => reject(new Error(`Could not load ${input}: ${error == null ? void 0 : error.message}`)))))).finally(() => loader.dispose == null ? void 0 : loader.dispose());
1668
1687
  };
1669
1688
  }
1670
- /**
1671
- * Synchronously loads and caches assets with a three loader.
1672
- *
1673
- * Note: this hook's caller must be wrapped with `React.Suspense`
1674
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1689
+ /**
1690
+ * Synchronously loads and caches assets with a three loader.
1691
+ *
1692
+ * Note: this hook's caller must be wrapped with `React.Suspense`
1693
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1675
1694
  */
1676
1695
  function useLoader(Proto, input, extensions, onProgress) {
1677
1696
  // Use suspense to load async assets
@@ -1683,16 +1702,16 @@ function useLoader(Proto, input, extensions, onProgress) {
1683
1702
  return Array.isArray(input) ? results : results[0];
1684
1703
  }
1685
1704
 
1686
- /**
1687
- * Preloads an asset into cache as a side-effect.
1705
+ /**
1706
+ * Preloads an asset into cache as a side-effect.
1688
1707
  */
1689
1708
  useLoader.preload = function (Proto, input, extensions) {
1690
1709
  const keys = Array.isArray(input) ? input : [input];
1691
1710
  return preload(loadingFn(extensions), [Proto, ...keys]);
1692
1711
  };
1693
1712
 
1694
- /**
1695
- * Removes a loaded asset from cache.
1713
+ /**
1714
+ * Removes a loaded asset from cache.
1696
1715
  */
1697
1716
  useLoader.clear = function (Proto, input) {
1698
1717
  const keys = Array.isArray(input) ? input : [input];
@@ -2089,10 +2108,10 @@ function Portal({
2089
2108
  children,
2090
2109
  container
2091
2110
  }) {
2092
- /** This has to be a component because it would not be able to call useThree/useStore otherwise since
2093
- * if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
2094
- * the "R3F hooks can only be used within the Canvas component!" warning:
2095
- * <Canvas>
2111
+ /** This has to be a component because it would not be able to call useThree/useStore otherwise since
2112
+ * if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
2113
+ * the "R3F hooks can only be used within the Canvas component!" warning:
2114
+ * <Canvas>
2096
2115
  * {createPortal(...)} */
2097
2116
  const {
2098
2117
  events,
@@ -122,6 +122,10 @@ function createRenderer(_roots, _getEventPriority) {
122
122
  child.dispatchEvent({
123
123
  type: 'added'
124
124
  });
125
+ parentInstance.dispatchEvent({
126
+ type: 'childadded',
127
+ child
128
+ });
125
129
  const restSiblings = parentInstance.children.filter(sibling => sibling !== child);
126
130
  const index = restSiblings.indexOf(beforeChild);
127
131
  parentInstance.children = [...restSiblings.slice(0, index), child, ...restSiblings.slice(index)];
@@ -382,12 +386,12 @@ function createRenderer(_roots, _getEventPriority) {
382
386
  }
383
387
 
384
388
  var _window$document, _window$navigator;
385
- /**
386
- * Returns `true` with correct TS type inference if an object has a configurable color space (since r152).
389
+ /**
390
+ * Returns `true` with correct TS type inference if an object has a configurable color space (since r152).
387
391
  */
388
392
  const hasColorSpace = object => 'colorSpace' in object || 'outputColorSpace' in object;
389
- /**
390
- * The current THREE.ColorManagement instance, if present.
393
+ /**
394
+ * The current THREE.ColorManagement instance, if present.
391
395
  */
392
396
  const getColorManagement = () => {
393
397
  var _ColorManagement;
@@ -396,14 +400,14 @@ const getColorManagement = () => {
396
400
  const isOrthographicCamera = def => def && def.isOrthographicCamera;
397
401
  const isRef = obj => obj && obj.hasOwnProperty('current');
398
402
 
399
- /**
400
- * An SSR-friendly useLayoutEffect.
401
- *
402
- * React currently throws a warning when using useLayoutEffect on the server.
403
- * To get around it, we can conditionally useEffect on the server (no-op) and
404
- * useLayoutEffect elsewhere.
405
- *
406
- * @see https://github.com/facebook/react/issues/14927
403
+ /**
404
+ * An SSR-friendly useLayoutEffect.
405
+ *
406
+ * React currently throws a warning when using useLayoutEffect on the server.
407
+ * To get around it, we can conditionally useEffect on the server (no-op) and
408
+ * useLayoutEffect elsewhere.
409
+ *
410
+ * @see https://github.com/facebook/react/issues/14927
407
411
  */
408
412
  const useIsomorphicLayoutEffect = typeof window !== 'undefined' && ((_window$document = window.document) != null && _window$document.createElement || ((_window$navigator = window.navigator) == null ? void 0 : _window$navigator.product) === 'ReactNative') ? React__namespace.useLayoutEffect : React__namespace.useEffect;
409
413
  function useMutableCallback(fn) {
@@ -448,16 +452,16 @@ function calculateDpr(dpr) {
448
452
  return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
449
453
  }
450
454
 
451
- /**
452
- * Returns instance root state
455
+ /**
456
+ * Returns instance root state
453
457
  */
454
458
  const getRootState = obj => {
455
459
  var _r3f;
456
460
  return (_r3f = obj.__r3f) == null ? void 0 : _r3f.root.getState();
457
461
  };
458
462
 
459
- /**
460
- * Returns the instances initial (outmost) root
463
+ /**
464
+ * Returns the instances initial (outmost) root
461
465
  */
462
466
  function findInitialRoot(child) {
463
467
  let root = child.__r3f.root;
@@ -514,8 +518,8 @@ const is = {
514
518
  }
515
519
  };
516
520
 
517
- /**
518
- * Collects nodes and materials from a THREE.Object3D.
521
+ /**
522
+ * Collects nodes and materials from a THREE.Object3D.
519
523
  */
520
524
  function buildGraph(object) {
521
525
  const data = {
@@ -857,9 +861,9 @@ function getEventPriority() {
857
861
  }
858
862
  }
859
863
 
860
- /**
861
- * Release pointer captures.
862
- * This is called by releasePointerCapture in the API, and when an object is removed.
864
+ /**
865
+ * Release pointer captures.
866
+ * This is called by releasePointerCapture in the API, and when an object is removed.
863
867
  */
864
868
  function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
865
869
  const captureData = captures.get(obj);
@@ -1194,19 +1198,19 @@ function createEvents(store) {
1194
1198
  // Check presence of handlers
1195
1199
  if (!(instance != null && instance.eventCount)) return;
1196
1200
 
1197
- /*
1198
- MAYBE TODO, DELETE IF NOT:
1199
- Check if the object is captured, captured events should not have intersects running in parallel
1200
- But wouldn't it be better to just replace capturedMap with a single entry?
1201
- Also, are we OK with straight up making picking up multiple objects impossible?
1202
-
1203
- const pointerId = (data as ThreeEvent<PointerEvent>).pointerId
1204
- if (pointerId !== undefined) {
1205
- const capturedMeshSet = internal.capturedMap.get(pointerId)
1206
- if (capturedMeshSet) {
1207
- const captured = capturedMeshSet.get(eventObject)
1208
- if (captured && captured.localState.stopped) return
1209
- }
1201
+ /*
1202
+ MAYBE TODO, DELETE IF NOT:
1203
+ Check if the object is captured, captured events should not have intersects running in parallel
1204
+ But wouldn't it be better to just replace capturedMap with a single entry?
1205
+ Also, are we OK with straight up making picking up multiple objects impossible?
1206
+
1207
+ const pointerId = (data as ThreeEvent<PointerEvent>).pointerId
1208
+ if (pointerId !== undefined) {
1209
+ const capturedMeshSet = internal.capturedMap.get(pointerId)
1210
+ if (capturedMeshSet) {
1211
+ const captured = capturedMeshSet.get(eventObject)
1212
+ if (captured && captured.localState.stopped) return
1213
+ }
1210
1214
  }*/
1211
1215
 
1212
1216
  if (isPointerMove) {
@@ -1512,21 +1516,21 @@ let globalEffects = new Set();
1512
1516
  let globalAfterEffects = new Set();
1513
1517
  let globalTailEffects = new Set();
1514
1518
 
1515
- /**
1516
- * Adds a global render callback which is called each frame.
1517
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
1519
+ /**
1520
+ * Adds a global render callback which is called each frame.
1521
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
1518
1522
  */
1519
1523
  const addEffect = callback => createSubs(callback, globalEffects);
1520
1524
 
1521
- /**
1522
- * Adds a global after-render callback which is called each frame.
1523
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
1525
+ /**
1526
+ * Adds a global after-render callback which is called each frame.
1527
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
1524
1528
  */
1525
1529
  const addAfterEffect = callback => createSubs(callback, globalAfterEffects);
1526
1530
 
1527
- /**
1528
- * Adds a global callback which is called when rendering stops.
1529
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
1531
+ /**
1532
+ * Adds a global callback which is called when rendering stops.
1533
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
1530
1534
  */
1531
1535
  const addTail = callback => createSubs(callback, globalTailEffects);
1532
1536
  function run(effects, timestamp) {
@@ -1572,6 +1576,7 @@ function render$1(timestamp, state, frame) {
1572
1576
  }
1573
1577
  function createLoop(roots) {
1574
1578
  let running = false;
1579
+ let useFrameInProgress = false;
1575
1580
  let repeat;
1576
1581
  let frame;
1577
1582
  let state;
@@ -1584,6 +1589,7 @@ function createLoop(roots) {
1584
1589
  flushGlobalEffects('before', timestamp);
1585
1590
 
1586
1591
  // Render all roots
1592
+ useFrameInProgress = true;
1587
1593
  for (const root of roots.values()) {
1588
1594
  var _state$gl$xr;
1589
1595
  state = root.store.getState();
@@ -1592,6 +1598,7 @@ function createLoop(roots) {
1592
1598
  repeat += render$1(timestamp, state);
1593
1599
  }
1594
1600
  }
1601
+ useFrameInProgress = false;
1595
1602
 
1596
1603
  // Run after-effects
1597
1604
  flushGlobalEffects('after', timestamp);
@@ -1610,8 +1617,20 @@ function createLoop(roots) {
1610
1617
  var _state$gl$xr2;
1611
1618
  if (!state) return roots.forEach(root => invalidate(root.store.getState(), frames));
1612
1619
  if ((_state$gl$xr2 = state.gl.xr) != null && _state$gl$xr2.isPresenting || !state.internal.active || state.frameloop === 'never') return;
1613
- // Increase frames, do not go higher than 60
1614
- state.internal.frames = Math.min(60, state.internal.frames + frames);
1620
+ if (frames > 1) {
1621
+ // legacy support for people using frames parameters
1622
+ // Increase frames, do not go higher than 60
1623
+ state.internal.frames = Math.min(60, state.internal.frames + frames);
1624
+ } else {
1625
+ if (useFrameInProgress) {
1626
+ //called from within a useFrame, it means the user wants an additional frame
1627
+ state.internal.frames = 2;
1628
+ } else {
1629
+ //the user need a new frame, no need to increment further than 1
1630
+ state.internal.frames = 1;
1631
+ }
1632
+ }
1633
+
1615
1634
  // If the render-loop isn't active, start it
1616
1635
  if (!running) {
1617
1636
  running = true;
@@ -1630,11 +1649,11 @@ function createLoop(roots) {
1630
1649
  };
1631
1650
  }
1632
1651
 
1633
- /**
1634
- * Exposes an object's {@link LocalState}.
1635
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useInstanceHandle
1636
- *
1637
- * **Note**: this is an escape hatch to react-internal fields. Expect this to change significantly between versions.
1652
+ /**
1653
+ * Exposes an object's {@link LocalState}.
1654
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useInstanceHandle
1655
+ *
1656
+ * **Note**: this is an escape hatch to react-internal fields. Expect this to change significantly between versions.
1638
1657
  */
1639
1658
  function useInstanceHandle(ref) {
1640
1659
  const instance = React__namespace.useRef(null);
@@ -1647,18 +1666,18 @@ function useStore() {
1647
1666
  return store;
1648
1667
  }
1649
1668
 
1650
- /**
1651
- * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1652
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1669
+ /**
1670
+ * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1671
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1653
1672
  */
1654
1673
  function useThree(selector = state => state, equalityFn) {
1655
1674
  return useStore()(selector, equalityFn);
1656
1675
  }
1657
1676
 
1658
- /**
1659
- * Executes a callback before render in a shared frame loop.
1660
- * Can order effects with render priority or manually render with a positive priority.
1661
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1677
+ /**
1678
+ * Executes a callback before render in a shared frame loop.
1679
+ * Can order effects with render priority or manually render with a positive priority.
1680
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1662
1681
  */
1663
1682
  function useFrame(callback, renderPriority = 0) {
1664
1683
  const store = useStore();
@@ -1670,9 +1689,9 @@ function useFrame(callback, renderPriority = 0) {
1670
1689
  return null;
1671
1690
  }
1672
1691
 
1673
- /**
1674
- * Returns a node graph of an object with named nodes & materials.
1675
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1692
+ /**
1693
+ * Returns a node graph of an object with named nodes & materials.
1694
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1676
1695
  */
1677
1696
  function useGraph(object) {
1678
1697
  return React__namespace.useMemo(() => buildGraph(object), [object]);
@@ -1694,11 +1713,11 @@ function loadingFn(extensions, onProgress) {
1694
1713
  }, onProgress, error => reject(new Error(`Could not load ${input}: ${error == null ? void 0 : error.message}`)))))).finally(() => loader.dispose == null ? void 0 : loader.dispose());
1695
1714
  };
1696
1715
  }
1697
- /**
1698
- * Synchronously loads and caches assets with a three loader.
1699
- *
1700
- * Note: this hook's caller must be wrapped with `React.Suspense`
1701
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1716
+ /**
1717
+ * Synchronously loads and caches assets with a three loader.
1718
+ *
1719
+ * Note: this hook's caller must be wrapped with `React.Suspense`
1720
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1702
1721
  */
1703
1722
  function useLoader(Proto, input, extensions, onProgress) {
1704
1723
  // Use suspense to load async assets
@@ -1710,16 +1729,16 @@ function useLoader(Proto, input, extensions, onProgress) {
1710
1729
  return Array.isArray(input) ? results : results[0];
1711
1730
  }
1712
1731
 
1713
- /**
1714
- * Preloads an asset into cache as a side-effect.
1732
+ /**
1733
+ * Preloads an asset into cache as a side-effect.
1715
1734
  */
1716
1735
  useLoader.preload = function (Proto, input, extensions) {
1717
1736
  const keys = Array.isArray(input) ? input : [input];
1718
1737
  return suspendReact.preload(loadingFn(extensions), [Proto, ...keys]);
1719
1738
  };
1720
1739
 
1721
- /**
1722
- * Removes a loaded asset from cache.
1740
+ /**
1741
+ * Removes a loaded asset from cache.
1723
1742
  */
1724
1743
  useLoader.clear = function (Proto, input) {
1725
1744
  const keys = Array.isArray(input) ? input : [input];
@@ -2116,10 +2135,10 @@ function Portal({
2116
2135
  children,
2117
2136
  container
2118
2137
  }) {
2119
- /** This has to be a component because it would not be able to call useThree/useStore otherwise since
2120
- * if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
2121
- * the "R3F hooks can only be used within the Canvas component!" warning:
2122
- * <Canvas>
2138
+ /** This has to be a component because it would not be able to call useThree/useStore otherwise since
2139
+ * if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
2140
+ * the "R3F hooks can only be used within the Canvas component!" warning:
2141
+ * <Canvas>
2123
2142
  * {createPortal(...)} */
2124
2143
  const {
2125
2144
  events,
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-b90e75f9.cjs.dev.js');
5
+ var index = require('./index-382d4f47.cjs.dev.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -251,9 +251,9 @@ const CanvasImpl = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
251
251
  }, fallback)));
252
252
  });
253
253
 
254
- /**
255
- * A DOM canvas which accepts threejs elements as children.
256
- * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
254
+ /**
255
+ * A DOM canvas which accepts threejs elements as children.
256
+ * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
257
257
  */
258
258
  const Canvas = /*#__PURE__*/React__namespace.forwardRef(function CanvasWrapper(props, ref) {
259
259
  return /*#__PURE__*/React__namespace.createElement(itsFine.FiberProvider, null, /*#__PURE__*/React__namespace.createElement(CanvasImpl, _extends({}, props, {
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-87af8422.cjs.prod.js');
5
+ var index = require('./index-e8d6e828.cjs.prod.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -251,9 +251,9 @@ const CanvasImpl = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
251
251
  }, fallback)));
252
252
  });
253
253
 
254
- /**
255
- * A DOM canvas which accepts threejs elements as children.
256
- * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
254
+ /**
255
+ * A DOM canvas which accepts threejs elements as children.
256
+ * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
257
257
  */
258
258
  const Canvas = /*#__PURE__*/React__namespace.forwardRef(function CanvasWrapper(props, ref) {
259
259
  return /*#__PURE__*/React__namespace.createElement(itsFine.FiberProvider, null, /*#__PURE__*/React__namespace.createElement(CanvasImpl, _extends({}, props, {