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

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 (27) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/declarations/src/core/events.d.ts +69 -69
  3. package/dist/declarations/src/core/hooks.d.ts +23 -21
  4. package/dist/declarations/src/core/index.d.ts +61 -57
  5. package/dist/declarations/src/core/loop.d.ts +13 -13
  6. package/dist/declarations/src/core/renderer.d.ts +51 -51
  7. package/dist/declarations/src/core/stages.d.ts +59 -0
  8. package/dist/declarations/src/core/store.d.ts +110 -95
  9. package/dist/declarations/src/core/utils.d.ts +81 -82
  10. package/dist/declarations/src/index.d.ts +12 -11
  11. package/dist/declarations/src/native/Canvas.d.ts +8 -8
  12. package/dist/declarations/src/native/events.d.ts +4 -4
  13. package/dist/declarations/src/native/polyfills.d.ts +1 -1
  14. package/dist/declarations/src/native.d.ts +10 -10
  15. package/dist/declarations/src/three-types.d.ts +331 -331
  16. package/dist/declarations/src/web/Canvas.d.ts +9 -9
  17. package/dist/declarations/src/web/events.d.ts +4 -4
  18. package/dist/{index-ca47b633.cjs.prod.js → index-b12f488b.cjs.prod.js} +290 -69
  19. package/dist/{index-0499a96a.cjs.dev.js → index-b3be5a63.cjs.dev.js} +290 -69
  20. package/dist/{index-6279214a.esm.js → index-e27d4a05.esm.js} +287 -70
  21. package/dist/react-three-fiber.cjs.dev.js +7 -1
  22. package/dist/react-three-fiber.cjs.prod.js +7 -1
  23. package/dist/react-three-fiber.esm.js +4 -2
  24. package/native/dist/react-three-fiber-native.cjs.dev.js +4 -1
  25. package/native/dist/react-three-fiber-native.cjs.prod.js +4 -1
  26. package/native/dist/react-three-fiber-native.esm.js +4 -2
  27. package/package.json +6 -6
@@ -10,12 +10,19 @@ var threeTypes = /*#__PURE__*/Object.freeze({
10
10
  __proto__: null
11
11
  });
12
12
 
13
- const isOrthographicCamera = def => def && def.isOrthographicCamera; // React currently throws a warning when using useLayoutEffect on the server.
14
- // To get around it, we can conditionally useEffect on the server (no-op) and
15
- // useLayoutEffect on the client.
13
+ var _window$document, _window$navigator;
14
+ const isOrthographicCamera = def => def && def.isOrthographicCamera;
15
+ /**
16
+ * An SSR-friendly useLayoutEffect.
17
+ *
18
+ * React currently throws a warning when using useLayoutEffect on the server.
19
+ * To get around it, we can conditionally useEffect on the server (no-op) and
20
+ * useLayoutEffect elsewhere.
21
+ *
22
+ * @see https://github.com/facebook/react/issues/14927
23
+ */
16
24
 
17
- const isSSR = typeof window === 'undefined' || !window.navigator || /ServerSideRendering|^Deno\//.test(window.navigator.userAgent);
18
- const useIsomorphicLayoutEffect = isSSR ? React.useEffect : React.useLayoutEffect;
25
+ 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;
19
26
  function useMutableCallback(fn) {
20
27
  const ref = React.useRef(fn);
21
28
  useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
@@ -331,12 +338,7 @@ function applyProps$1(instance, data) {
331
338
 
332
339
  if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
333
340
  else if (targetProp instanceof THREE.Layers && value instanceof THREE.Layers) targetProp.mask = value.mask; // Otherwise just set ...
334
- else targetProp.set(value); // For versions of three which don't support THREE.ColorManagement,
335
- // Auto-convert sRGB colors
336
- // https://github.com/pmndrs/react-three-fiber/issues/344
337
-
338
- const supportsColorManagement = ('ColorManagement' in THREE);
339
- if (!supportsColorManagement && !rootState.linear && isColor) targetProp.convertSRGBToLinear();
341
+ else targetProp.set(value);
340
342
  } // Else, just overwrite the value
341
343
 
342
344
  } else {
@@ -391,15 +393,6 @@ function updateCamera(camera, size) {
391
393
  camera.updateMatrixWorld();
392
394
  }
393
395
  }
394
- /**
395
- * Safely sets a deeply-nested value on an object.
396
- */
397
-
398
- function setDeep(obj, value, keys) {
399
- const key = keys.pop();
400
- const target = keys.reduce((acc, key) => acc[key], obj);
401
- return target[key] = value;
402
- }
403
396
 
404
397
  function makeId(event) {
405
398
  return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
@@ -1036,7 +1029,10 @@ function createRenderer(_roots, _getEventPriority) {
1036
1029
  }
1037
1030
  }
1038
1031
  });
1039
- }
1032
+ } // Don't handle text instances, warn on undefined behavior
1033
+
1034
+
1035
+ const handleTextInstance = () => console.warn('Text is not allowed in the R3F tree! This could be stray whitespace or characters.');
1040
1036
 
1041
1037
  const reconciler = Reconciler({
1042
1038
  createInstance,
@@ -1050,13 +1046,20 @@ function createRenderer(_roots, _getEventPriority) {
1050
1046
  supportsHydration: false,
1051
1047
  noTimeout: -1,
1052
1048
  appendChildToContainer: (container, child) => {
1049
+ if (!child) return;
1053
1050
  const scene = container.getState().scene; // Link current root to the default scene
1054
1051
 
1055
1052
  scene.__r3f.root = container;
1056
1053
  appendChild(scene, child);
1057
1054
  },
1058
- removeChildFromContainer: (container, child) => removeChild(container.getState().scene, child),
1059
- insertInContainerBefore: (container, child, beforeChild) => insertBefore(container.getState().scene, child, beforeChild),
1055
+ removeChildFromContainer: (container, child) => {
1056
+ if (!child) return;
1057
+ removeChild(container.getState().scene, child);
1058
+ },
1059
+ insertInContainerBefore: (container, child, beforeChild) => {
1060
+ if (!child || !beforeChild) return;
1061
+ insertBefore(container.getState().scene, child, beforeChild);
1062
+ },
1060
1063
  getRootHostContext: () => null,
1061
1064
  getChildHostContext: parentHostContext => parentHostContext,
1062
1065
 
@@ -1148,13 +1151,9 @@ function createRenderer(_roots, _getEventPriority) {
1148
1151
  invalidateInstance(instance);
1149
1152
  },
1150
1153
 
1151
- createTextInstance: () => {
1152
- throw new Error('Text is not allowed in the R3F tree.');
1153
- },
1154
- hideTextInstance: () => {
1155
- throw new Error('Text is not allowed in the R3F tree.');
1156
- },
1157
- unhideTextInstance: () => {},
1154
+ createTextInstance: handleTextInstance,
1155
+ hideTextInstance: handleTextInstance,
1156
+ unhideTextInstance: handleTextInstance,
1158
1157
  // https://github.com/pmndrs/react-three-fiber/pull/2360#discussion_r916356874
1159
1158
  // @ts-ignore
1160
1159
  getCurrentEventPriority: () => _getEventPriority ? _getEventPriority() : DefaultEventPriority,
@@ -1172,6 +1171,7 @@ function createRenderer(_roots, _getEventPriority) {
1172
1171
  };
1173
1172
  }
1174
1173
 
1174
+ // Keys that shouldn't be copied between R3F stores
1175
1175
  const privateKeys = ['set', 'get', 'setSize', 'setFrameloop', 'setDpr', 'events', 'invalidate', 'advance', 'size', 'viewport'];
1176
1176
  const isRenderer = def => !!(def != null && def.render);
1177
1177
  const context = /*#__PURE__*/React.createContext(null);
@@ -1319,8 +1319,14 @@ const createStore = (invalidate, advance) => {
1319
1319
  }
1320
1320
  };
1321
1321
  }),
1322
- setFrameloop: (frameloop = 'always') => {
1323
- const clock = get().clock; // if frameloop === "never" clock.elapsedTime is updated using advance(timestamp)
1322
+ setFrameloop: frameloop => {
1323
+ var _frameloop$mode, _frameloop$render, _frameloop$maxDelta;
1324
+
1325
+ const state = get();
1326
+ const mode = typeof frameloop === 'string' ? frameloop : (frameloop == null ? void 0 : frameloop.mode) === 'auto' ? 'always' : (_frameloop$mode = frameloop == null ? void 0 : frameloop.mode) != null ? _frameloop$mode : state.frameloop;
1327
+ const render = typeof frameloop === 'string' ? state.internal.render : (_frameloop$render = frameloop == null ? void 0 : frameloop.render) != null ? _frameloop$render : state.internal.render;
1328
+ const maxDelta = typeof frameloop === 'string' ? state.internal.maxDelta : (_frameloop$maxDelta = frameloop == null ? void 0 : frameloop.maxDelta) != null ? _frameloop$maxDelta : state.internal.maxDelta;
1329
+ const clock = state.clock; // if frameloop === "never" clock.elapsedTime is updated using advance(timestamp)
1324
1330
 
1325
1331
  clock.stop();
1326
1332
  clock.elapsedTime = 0;
@@ -1331,28 +1337,44 @@ const createStore = (invalidate, advance) => {
1331
1337
  }
1332
1338
 
1333
1339
  set(() => ({
1334
- frameloop
1340
+ frameloop: mode,
1341
+ internal: { ...state.internal,
1342
+ render,
1343
+ maxDelta
1344
+ }
1335
1345
  }));
1336
1346
  },
1337
1347
  previousRoot: undefined,
1338
1348
  internal: {
1339
- active: false,
1340
- priority: 0,
1341
- frames: 0,
1342
- lastEvent: /*#__PURE__*/React.createRef(),
1349
+ // Events
1343
1350
  interaction: [],
1344
1351
  hovered: new Map(),
1345
1352
  subscribers: [],
1346
1353
  initialClick: [0, 0],
1347
1354
  initialHits: [],
1348
1355
  capturedMap: new Map(),
1356
+ lastEvent: /*#__PURE__*/React.createRef(),
1357
+ // Updates
1358
+ active: false,
1359
+ frames: 0,
1360
+ stages: [],
1361
+ render: 'auto',
1362
+ maxDelta: 1 / 10,
1363
+ priority: 0,
1349
1364
  subscribe: (ref, priority, store) => {
1350
- const internal = get().internal; // If this subscription was given a priority, it takes rendering into its own hands
1365
+ const state = get();
1366
+ const internal = state.internal; // If this subscription was given a priority, it takes rendering into its own hands
1351
1367
  // For that reason we switch off automatic rendering and increase the manual flag
1352
1368
  // As long as this flag is positive there can be no internal rendering at all
1353
1369
  // because there could be multiple render subscriptions
1354
1370
 
1355
- internal.priority = internal.priority + (priority > 0 ? 1 : 0);
1371
+ internal.priority = internal.priority + (priority > 0 ? 1 : 0); // We use the render flag and deprecate priority
1372
+
1373
+ if (internal.priority && state.internal.render === 'auto') set(() => ({
1374
+ internal: { ...state.internal,
1375
+ render: 'manual'
1376
+ }
1377
+ }));
1356
1378
  internal.subscribers.push({
1357
1379
  ref,
1358
1380
  priority,
@@ -1362,11 +1384,18 @@ const createStore = (invalidate, advance) => {
1362
1384
 
1363
1385
  internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
1364
1386
  return () => {
1365
- const internal = get().internal;
1387
+ const state = get();
1388
+ const internal = state.internal;
1366
1389
 
1367
1390
  if (internal != null && internal.subscribers) {
1368
1391
  // Decrease manual flag if this subscription had a priority
1369
- internal.priority = internal.priority - (priority > 0 ? 1 : 0); // Remove subscriber from list
1392
+ internal.priority = internal.priority - (priority > 0 ? 1 : 0); // We use the render flag and deprecate priority
1393
+
1394
+ if (!internal.priority && state.internal.render === 'manual') set(() => ({
1395
+ internal: { ...state.internal,
1396
+ render: 'auto'
1397
+ }
1398
+ })); // Remove subscriber from list
1370
1399
 
1371
1400
  internal.subscribers = internal.subscribers.filter(s => s.ref !== ref);
1372
1401
  }
@@ -1422,8 +1451,6 @@ function createSubs(callback, subs) {
1422
1451
  subs.add(sub);
1423
1452
  return () => void subs.delete(sub);
1424
1453
  }
1425
-
1426
- let i;
1427
1454
  let globalEffects = new Set();
1428
1455
  let globalAfterEffects = new Set();
1429
1456
  let globalTailEffects = new Set();
@@ -1452,10 +1479,7 @@ function run(effects, timestamp) {
1452
1479
  }) => callback(timestamp));
1453
1480
  }
1454
1481
 
1455
- let subscribers;
1456
- let subscription;
1457
-
1458
- function render$1(timestamp, state, frame) {
1482
+ function update(timestamp, state, frame) {
1459
1483
  // Run local effects
1460
1484
  let delta = state.clock.getDelta(); // In frameloop='never' mode, clock times are updated using the provided timestamp
1461
1485
 
@@ -1463,18 +1487,14 @@ function render$1(timestamp, state, frame) {
1463
1487
  delta = timestamp - state.clock.elapsedTime;
1464
1488
  state.clock.oldTime = state.clock.elapsedTime;
1465
1489
  state.clock.elapsedTime = timestamp;
1466
- } // Call subscribers (useFrame)
1467
-
1468
-
1469
- subscribers = state.internal.subscribers;
1490
+ } else {
1491
+ delta = Math.max(Math.min(delta, state.internal.maxDelta), 0);
1492
+ } // Call subscribers (useUpdate)
1470
1493
 
1471
- for (i = 0; i < subscribers.length; i++) {
1472
- subscription = subscribers[i];
1473
- subscription.ref.current(subscription.store.getState(), delta, frame);
1474
- } // Render content
1475
1494
 
1476
-
1477
- if (!state.internal.priority && state.gl.render) state.gl.render(state.scene, state.camera); // Decrease frame count
1495
+ for (const stage of state.internal.stages) {
1496
+ stage.frame(delta, frame);
1497
+ }
1478
1498
 
1479
1499
  state.internal.frames = Math.max(0, state.internal.frames - 1);
1480
1500
  return state.frameloop === 'always' ? 1 : state.internal.frames;
@@ -1499,7 +1519,7 @@ function createLoop(roots) {
1499
1519
  state = root.store.getState(); // If the frameloop is invalidated, do not run another frame
1500
1520
 
1501
1521
  if (state.internal.active && (state.frameloop === 'always' || state.internal.frames > 0) && !((_state$gl$xr = state.gl.xr) != null && _state$gl$xr.isPresenting)) {
1502
- repeat += render$1(timestamp, state);
1522
+ repeat += update(timestamp, state);
1503
1523
  }
1504
1524
  }); // Run after-effects
1505
1525
 
@@ -1530,7 +1550,7 @@ function createLoop(roots) {
1530
1550
 
1531
1551
  function advance(timestamp, runGlobalEffects = true, state, frame) {
1532
1552
  if (runGlobalEffects) run(globalEffects, timestamp);
1533
- if (!state) roots.forEach(root => render$1(timestamp, root.store.getState()));else render$1(timestamp, state, frame);
1553
+ if (!state) roots.forEach(root => update(timestamp, root.store.getState()));else update(timestamp, state, frame);
1534
1554
  if (runGlobalEffects) run(globalAfterEffects, timestamp);
1535
1555
  }
1536
1556
 
@@ -1551,6 +1571,154 @@ function createLoop(roots) {
1551
1571
  };
1552
1572
  }
1553
1573
 
1574
+ /**
1575
+ * Class representing a stage that updates every frame.
1576
+ * Stages are used to build a lifecycle of effects for an app's frameloop.
1577
+ */
1578
+ class Stage {
1579
+ constructor() {
1580
+ this.subscribers = [];
1581
+ this._frameTime = 0;
1582
+ }
1583
+ /**
1584
+ * Executes all callback subscriptions on the stage.
1585
+ * @param delta - Delta time between frame calls.
1586
+ * @param [frame] - The XR frame if it exists.
1587
+ */
1588
+
1589
+
1590
+ frame(delta, frame) {
1591
+ const subs = this.subscribers;
1592
+ const initialTime = performance.now();
1593
+
1594
+ for (let i = 0; i < subs.length; i++) {
1595
+ subs[i].ref.current(subs[i].store.getState(), delta, frame);
1596
+ }
1597
+
1598
+ this._frameTime = performance.now() - initialTime;
1599
+ }
1600
+ /**
1601
+ * Adds a callback subscriber to the stage.
1602
+ * @param ref - The mutable callback reference.
1603
+ * @param store - The store to be used with the callback execution.
1604
+ * @returns A function to remove the subscription.
1605
+ */
1606
+
1607
+
1608
+ add(ref, store) {
1609
+ this.subscribers.push({
1610
+ ref,
1611
+ store
1612
+ });
1613
+ return () => {
1614
+ this.subscribers = this.subscribers.filter(sub => {
1615
+ return sub.ref !== ref;
1616
+ });
1617
+ };
1618
+ }
1619
+
1620
+ get frameTime() {
1621
+ return this._frameTime;
1622
+ }
1623
+
1624
+ } // Using Unity's fixedStep default.
1625
+
1626
+ const FPS_50 = 1 / 50;
1627
+ /**
1628
+ * Class representing a stage that updates every frame at a fixed rate.
1629
+ * @param name - Name of the stage.
1630
+ * @param [fixedStep] - Fixed step rate.
1631
+ * @param [maxSubsteps] - Maximum number of substeps.
1632
+ */
1633
+
1634
+ class FixedStage extends Stage {
1635
+ constructor(fixedStep, maxSubSteps) {
1636
+ super();
1637
+ this._fixedStep = fixedStep != null ? fixedStep : FPS_50;
1638
+ this._maxSubsteps = maxSubSteps != null ? maxSubSteps : 6;
1639
+ this._accumulator = 0;
1640
+ this._alpha = 0;
1641
+ this._fixedFrameTime = 0;
1642
+ this._substepTimes = [];
1643
+ }
1644
+ /**
1645
+ * Executes all callback subscriptions on the stage.
1646
+ * @param delta - Delta time between frame calls.
1647
+ * @param [frame] - The XR frame if it exists.
1648
+ */
1649
+
1650
+
1651
+ frame(delta, frame) {
1652
+ const initialTime = performance.now();
1653
+ let substeps = 0;
1654
+ this._substepTimes = [];
1655
+ this._accumulator += delta;
1656
+
1657
+ while (this._accumulator >= this._fixedStep && substeps < this._maxSubsteps) {
1658
+ this._accumulator -= this._fixedStep;
1659
+ substeps++;
1660
+ super.frame(this._fixedStep, frame);
1661
+
1662
+ this._substepTimes.push(super.frameTime);
1663
+ }
1664
+
1665
+ this._fixedFrameTime = performance.now() - initialTime; // The accumulator will only be larger than the fixed step if we had to
1666
+ // bail early due to hitting the max substep limit or execution time lagging.
1667
+ // In that case, we want to shave off the excess so we don't fall behind next frame.
1668
+
1669
+ this._accumulator = this._accumulator % this._fixedStep;
1670
+ this._alpha = this._accumulator / this._fixedStep;
1671
+ }
1672
+
1673
+ get frameTime() {
1674
+ return this._fixedFrameTime;
1675
+ }
1676
+
1677
+ get substepTimes() {
1678
+ return this._substepTimes;
1679
+ }
1680
+
1681
+ get fixedStep() {
1682
+ return this._fixedStep;
1683
+ }
1684
+
1685
+ set fixedStep(fixedStep) {
1686
+ this._fixedStep = fixedStep;
1687
+ }
1688
+
1689
+ get maxSubsteps() {
1690
+ return this._maxSubsteps;
1691
+ }
1692
+
1693
+ set maxSubsteps(maxSubsteps) {
1694
+ this._maxSubsteps = maxSubsteps;
1695
+ }
1696
+
1697
+ get accumulator() {
1698
+ return this._accumulator;
1699
+ }
1700
+
1701
+ get alpha() {
1702
+ return this._alpha;
1703
+ }
1704
+
1705
+ }
1706
+ const Early = new Stage();
1707
+ const Fixed = new FixedStage();
1708
+ const Update = new Stage();
1709
+ const Late = new Stage();
1710
+ const Render = new Stage();
1711
+ const After = new Stage();
1712
+ const Stages = {
1713
+ Early,
1714
+ Fixed,
1715
+ Update,
1716
+ Late,
1717
+ Render,
1718
+ After
1719
+ };
1720
+ const Lifecycle = [Early, Fixed, Update, Late, Render, After];
1721
+
1554
1722
  function useStore() {
1555
1723
  const store = React.useContext(context);
1556
1724
  if (!store) throw `R3F hooks can only be used within the Canvas component!`;
@@ -1579,6 +1747,21 @@ function useFrame(callback, renderPriority = 0) {
1579
1747
  useIsomorphicLayoutEffect(() => subscribe(ref, renderPriority, store), [renderPriority, subscribe, store]);
1580
1748
  return null;
1581
1749
  }
1750
+ /**
1751
+ * Executes a callback in a given update stage.
1752
+ * Uses the stage instance to indetify which stage to target in the lifecycle.
1753
+ */
1754
+
1755
+ function useUpdate(callback, stage = Stages.Update) {
1756
+ const store = useStore();
1757
+ const stages = store.getState().internal.stages; // Memoize ref
1758
+
1759
+ const ref = useMutableCallback(callback); // Throw an error if a stage does not exist in the lifecycle
1760
+
1761
+ if (!stages.includes(stage)) throw new Error(`An invoked stage does not exist in the lifecycle.`); // Subscribe on mount, unsubscribe on unmount
1762
+
1763
+ useIsomorphicLayoutEffect(() => stage.add(ref, store), [stage]);
1764
+ }
1582
1765
  /**
1583
1766
  * Returns a node graph of an object with named nodes & materials.
1584
1767
  * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
@@ -1660,6 +1843,43 @@ const createRendererInstance = (gl, canvas) => {
1660
1843
  });
1661
1844
  };
1662
1845
 
1846
+ const createStages = (stages, store) => {
1847
+ var _stages;
1848
+
1849
+ const state = store.getState();
1850
+ let subscribers;
1851
+ 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.';
1855
+ state.set(({
1856
+ internal
1857
+ }) => ({
1858
+ internal: { ...internal,
1859
+ stages: stages
1860
+ }
1861
+ })); // Add useFrame loop to update stage
1862
+
1863
+ const frameCallback = {
1864
+ current: (state, delta, frame) => {
1865
+ subscribers = state.internal.subscribers;
1866
+
1867
+ for (let i = 0; i < subscribers.length; i++) {
1868
+ subscription = subscribers[i];
1869
+ subscription.ref.current(subscription.store.getState(), delta, frame);
1870
+ }
1871
+ }
1872
+ };
1873
+ Stages.Update.add(frameCallback, store); // Add render callback to render stage
1874
+
1875
+ const renderCallback = {
1876
+ current: state => {
1877
+ if (state.internal.render === 'auto' && state.gl.render) state.gl.render(state.scene, state.camera);
1878
+ }
1879
+ };
1880
+ Stages.Render.add(renderCallback, store);
1881
+ };
1882
+
1663
1883
  function createRoot(canvas) {
1664
1884
  // Check against mistaken use of createRoot
1665
1885
  let prevRoot = roots.get(canvas);
@@ -1701,7 +1921,8 @@ function createRoot(canvas) {
1701
1921
  performance,
1702
1922
  raycaster: raycastOptions,
1703
1923
  camera: cameraOptions,
1704
- onPointerMissed
1924
+ onPointerMissed,
1925
+ stages
1705
1926
  } = props;
1706
1927
  let state = store.getState(); // Set up renderer (one time only!)
1707
1928
 
@@ -1792,14 +2013,8 @@ function createRoot(canvas) {
1792
2013
  if (!isBoolean) Object.assign(gl.shadowMap, shadows);else gl.shadowMap.type = THREE.PCFSoftShadowMap;
1793
2014
  if (old !== gl.shadowMap.enabled) gl.shadowMap.needsUpdate = true;
1794
2015
  }
1795
- } // Safely set color management if available.
1796
- // Avoid accessing THREE.ColorManagement to play nice with older versions
1797
-
1798
-
1799
- if ('ColorManagement' in THREE) {
1800
- setDeep(THREE, legacy, ['ColorManagement', 'legacyMode']);
1801
- }
1802
-
2016
+ } // Set color management
2017
+ THREE.ColorManagement.legacyMode = legacy;
1803
2018
  const outputEncoding = linear ? THREE.LinearEncoding : THREE.sRGBEncoding;
1804
2019
  const toneMapping = flat ? THREE.NoToneMapping : THREE.ACESFilmicToneMapping;
1805
2020
  if (gl.outputEncoding !== outputEncoding) gl.outputEncoding = outputEncoding;
@@ -1850,7 +2065,9 @@ function createRoot(canvas) {
1850
2065
  performance: { ...state.performance,
1851
2066
  ...performance
1852
2067
  }
1853
- })); // Set locals
2068
+ })); // Create update stages.
2069
+
2070
+ if (stages !== state.internal.stages) createStages(stages, store); // Set locals
1854
2071
 
1855
2072
  onCreated = onCreatedCallback;
1856
2073
  configured = true;
@@ -2062,4 +2279,4 @@ reconciler.injectIntoDevTools({
2062
2279
  });
2063
2280
  const act = React.unstable_act;
2064
2281
 
2065
- export { Block as B, ErrorBoundary as E, createRoot as a, useIsomorphicLayoutEffect as b, createEvents as c, unmountComponentAtNode as d, extend as e, context as f, createPortal as g, reconciler as h, applyProps as i, dispose as j, invalidate as k, advance as l, addEffect as m, addAfterEffect as n, addTail as o, getRootState as p, act as q, render as r, roots as s, threeTypes as t, useMutableCallback as u, useStore as v, useThree as w, useFrame as x, useGraph as y, useLoader as z };
2282
+ export { useGraph as A, Block as B, useLoader as C, ErrorBoundary as E, FixedStage as F, Stage as S, createRoot as a, useIsomorphicLayoutEffect as b, createEvents as c, unmountComponentAtNode as d, extend as e, Stages as f, context as g, createPortal as h, reconciler as i, applyProps as j, dispose as k, invalidate as l, advance as m, addEffect as n, addAfterEffect as o, addTail as p, getRootState as q, render as r, act as s, threeTypes as t, useMutableCallback as u, roots as v, useStore as w, useThree as x, useFrame as y, useUpdate as z };
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-0499a96a.cjs.dev.js');
5
+ var index = require('./index-b3be5a63.cjs.dev.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -138,6 +138,7 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
138
138
  camera,
139
139
  onPointerMissed,
140
140
  onCreated,
141
+ stages,
141
142
  ...props
142
143
  }, forwardedRef) {
143
144
  // Create a known catalogue of Threejs-native elements
@@ -180,6 +181,7 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
180
181
  performance,
181
182
  raycaster,
182
183
  camera,
184
+ stages,
183
185
  size: containerRect,
184
186
  // Pass mutable reference to onPointerMissed so it's free to update
185
187
  onPointerMissed: (...args) => handlePointerMissed.current == null ? void 0 : handlePointerMissed.current(...args),
@@ -226,7 +228,10 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
226
228
  }, fallback)));
227
229
  });
228
230
 
231
+ exports.FixedStage = index.FixedStage;
229
232
  exports.ReactThreeFiber = index.threeTypes;
233
+ exports.Stage = index.Stage;
234
+ exports.Stages = index.Stages;
230
235
  exports._roots = index.roots;
231
236
  exports.act = index.act;
232
237
  exports.addAfterEffect = index.addAfterEffect;
@@ -250,5 +255,6 @@ exports.useGraph = index.useGraph;
250
255
  exports.useLoader = index.useLoader;
251
256
  exports.useStore = index.useStore;
252
257
  exports.useThree = index.useThree;
258
+ exports.useUpdate = index.useUpdate;
253
259
  exports.Canvas = Canvas;
254
260
  exports.events = createPointerEvents;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-ca47b633.cjs.prod.js');
5
+ var index = require('./index-b12f488b.cjs.prod.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -138,6 +138,7 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
138
138
  camera,
139
139
  onPointerMissed,
140
140
  onCreated,
141
+ stages,
141
142
  ...props
142
143
  }, forwardedRef) {
143
144
  // Create a known catalogue of Threejs-native elements
@@ -180,6 +181,7 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
180
181
  performance,
181
182
  raycaster,
182
183
  camera,
184
+ stages,
183
185
  size: containerRect,
184
186
  // Pass mutable reference to onPointerMissed so it's free to update
185
187
  onPointerMissed: (...args) => handlePointerMissed.current == null ? void 0 : handlePointerMissed.current(...args),
@@ -226,7 +228,10 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
226
228
  }, fallback)));
227
229
  });
228
230
 
231
+ exports.FixedStage = index.FixedStage;
229
232
  exports.ReactThreeFiber = index.threeTypes;
233
+ exports.Stage = index.Stage;
234
+ exports.Stages = index.Stages;
230
235
  exports._roots = index.roots;
231
236
  exports.act = index.act;
232
237
  exports.addAfterEffect = index.addAfterEffect;
@@ -250,5 +255,6 @@ exports.useGraph = index.useGraph;
250
255
  exports.useLoader = index.useLoader;
251
256
  exports.useStore = index.useStore;
252
257
  exports.useThree = index.useThree;
258
+ exports.useUpdate = index.useUpdate;
253
259
  exports.Canvas = Canvas;
254
260
  exports.events = createPointerEvents;
@@ -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-6279214a.esm.js';
2
- export { t as ReactThreeFiber, s as _roots, q as act, n as addAfterEffect, m as addEffect, o as addTail, l as advance, i as applyProps, f as context, c as createEvents, g as createPortal, a as createRoot, j as dispose, e as extend, p as getRootState, k as invalidate, h as reconciler, r as render, d as unmountComponentAtNode, x as useFrame, y as useGraph, z as useLoader, v as useStore, w as useThree } from './index-6279214a.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-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';
3
3
  import _extends from '@babel/runtime/helpers/esm/extends';
4
4
  import * as React from 'react';
5
5
  import * as THREE from 'three';
@@ -111,6 +111,7 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
111
111
  camera,
112
112
  onPointerMissed,
113
113
  onCreated,
114
+ stages,
114
115
  ...props
115
116
  }, forwardedRef) {
116
117
  // Create a known catalogue of Threejs-native elements
@@ -153,6 +154,7 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
153
154
  performance,
154
155
  raycaster,
155
156
  camera,
157
+ stages,
156
158
  size: containerRect,
157
159
  // Pass mutable reference to onPointerMissed so it's free to update
158
160
  onPointerMissed: (...args) => handlePointerMissed.current == null ? void 0 : handlePointerMissed.current(...args),
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('../../dist/index-0499a96a.cjs.dev.js');
5
+ var index = require('../../dist/index-b3be5a63.cjs.dev.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -250,6 +250,7 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(({
250
250
  camera,
251
251
  onPointerMissed,
252
252
  onCreated,
253
+ stages,
253
254
  ...props
254
255
  }, forwardedRef) => {
255
256
  // Create a known catalogue of Threejs-native elements
@@ -324,6 +325,7 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(({
324
325
  performance,
325
326
  raycaster,
326
327
  camera,
328
+ stages,
327
329
  // expo-gl can only render at native dpr/resolution
328
330
  // https://github.com/expo/expo-three/issues/39
329
331
  dpr: reactNative.PixelRatio.get(),
@@ -402,5 +404,6 @@ exports.useGraph = index.useGraph;
402
404
  exports.useLoader = index.useLoader;
403
405
  exports.useStore = index.useStore;
404
406
  exports.useThree = index.useThree;
407
+ exports.useUpdate = index.useUpdate;
405
408
  exports.Canvas = Canvas;
406
409
  exports.events = createTouchEvents;