@react-three/fiber 9.0.4 → 9.1.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 +1136 -1124
  2. package/dist/declarations/src/core/events.d.ts +92 -92
  3. package/dist/declarations/src/core/hooks.d.ts +53 -53
  4. package/dist/declarations/src/core/index.d.ts +13 -13
  5. package/dist/declarations/src/core/loop.d.ts +31 -31
  6. package/dist/declarations/src/core/reconciler.d.ts +50 -50
  7. package/dist/declarations/src/core/renderer.d.ts +89 -89
  8. package/dist/declarations/src/core/store.d.ts +130 -130
  9. package/dist/declarations/src/core/utils.d.ts +190 -187
  10. package/dist/declarations/src/index.d.ts +6 -6
  11. package/dist/declarations/src/native/Canvas.d.ts +13 -13
  12. package/dist/declarations/src/native/events.d.ts +4 -4
  13. package/dist/declarations/src/native.d.ts +6 -6
  14. package/dist/declarations/src/three-types.d.ts +67 -67
  15. package/dist/declarations/src/web/Canvas.d.ts +23 -23
  16. package/dist/declarations/src/web/events.d.ts +4 -4
  17. package/dist/{events-2895749c.esm.js → events-9ea6854d.esm.js} +114 -95
  18. package/dist/{events-cee74b95.cjs.dev.js → events-b2f77bcf.cjs.dev.js} +114 -95
  19. package/dist/{events-ff8de4d2.cjs.prod.js → events-fed10990.cjs.prod.js} +114 -95
  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 +4 -4
  24. package/native/dist/react-three-fiber-native.cjs.prod.js +4 -4
  25. package/native/dist/react-three-fiber-native.esm.js +5 -5
  26. package/native/package.json +5 -5
  27. package/package.json +3 -2
  28. package/readme.md +253 -253
@@ -12,30 +12,35 @@ var threeTypes = /*#__PURE__*/Object.freeze({
12
12
  __proto__: null
13
13
  });
14
14
 
15
- /**
16
- * Returns the instance's initial (outmost) root.
15
+ /**
16
+ * Returns the instance's initial (outmost) root.
17
17
  */
18
18
  function findInitialRoot(instance) {
19
19
  let root = instance.root;
20
20
  while (root.getState().previousRoot) root = root.getState().previousRoot;
21
21
  return root;
22
22
  }
23
- /**
24
- * Safely flush async effects when testing, simulating a legacy root.
23
+ /**
24
+ * Safely flush async effects when testing, simulating a legacy root.
25
25
  */
26
- const act = React.act;
26
+ const act = cb => {
27
+ if ('act' in React) {
28
+ return React.act(cb);
29
+ }
30
+ throw new Error('act(...) is not supported in production builds of React');
31
+ };
27
32
  const isOrthographicCamera = def => def && def.isOrthographicCamera;
28
33
  const isRef = obj => obj && obj.hasOwnProperty('current');
29
34
  const isColorRepresentation = value => value != null && (typeof value === 'string' || typeof value === 'number' || value.isColor);
30
35
 
31
- /**
32
- * An SSR-friendly useLayoutEffect.
33
- *
34
- * React currently throws a warning when using useLayoutEffect on the server.
35
- * To get around it, we can conditionally useEffect on the server (no-op) and
36
- * useLayoutEffect elsewhere.
37
- *
38
- * @see https://github.com/facebook/react/issues/14927
36
+ /**
37
+ * An SSR-friendly useLayoutEffect.
38
+ *
39
+ * React currently throws a warning when using useLayoutEffect on the server.
40
+ * To get around it, we can conditionally useEffect on the server (no-op) and
41
+ * useLayoutEffect elsewhere.
42
+ *
43
+ * @see https://github.com/facebook/react/issues/14927
39
44
  */
40
45
  const useIsomorphicLayoutEffect = /* @__PURE__ */((_window$document, _window$navigator) => typeof window !== 'undefined' && (((_window$document = window.document) == null ? void 0 : _window$document.createElement) || ((_window$navigator = window.navigator) == null ? void 0 : _window$navigator.product) === 'ReactNative'))() ? React.useLayoutEffect : React.useEffect;
41
46
  function useMutableCallback(fn) {
@@ -43,8 +48,8 @@ function useMutableCallback(fn) {
43
48
  useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
44
49
  return ref;
45
50
  }
46
- /**
47
- * Bridges renderer Context and StrictMode from a primary renderer.
51
+ /**
52
+ * Bridges renderer Context and StrictMode from a primary renderer.
48
53
  */
49
54
  function useBridge() {
50
55
  const fiber = useFiber();
@@ -96,8 +101,8 @@ function calculateDpr(dpr) {
96
101
  return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
97
102
  }
98
103
 
99
- /**
100
- * Returns instance root state
104
+ /**
105
+ * Returns instance root state
101
106
  */
102
107
  function getRootState(obj) {
103
108
  var _r3f;
@@ -158,12 +163,14 @@ const is = {
158
163
  function buildGraph(object) {
159
164
  const data = {
160
165
  nodes: {},
161
- materials: {}
166
+ materials: {},
167
+ meshes: {}
162
168
  };
163
169
  if (object) {
164
170
  object.traverse(obj => {
165
171
  if (obj.name) data.nodes[obj.name] = obj;
166
172
  if (obj.material && !data.materials[obj.material.name]) data.materials[obj.material.name] = obj.material;
173
+ if (obj.isMesh && !data.meshes[obj.name]) data.meshes[obj.name] = obj;
167
174
  });
168
175
  }
169
176
  return data;
@@ -210,7 +217,6 @@ function prepare(target, root, type, props) {
210
217
  return instance;
211
218
  }
212
219
  function resolve(root, key) {
213
- var _target;
214
220
  let target = root[key];
215
221
  if (!key.includes('-')) return {
216
222
  root,
@@ -219,12 +225,16 @@ function resolve(root, key) {
219
225
  };
220
226
 
221
227
  // Resolve pierced target
222
- const chain = key.split('-');
223
- target = chain.reduce((acc, key) => acc[key], root);
224
- key = chain.pop();
228
+ target = root;
229
+ for (const part of key.split('-')) {
230
+ var _target;
231
+ key = part;
232
+ root = target;
233
+ target = (_target = target) == null ? void 0 : _target[key];
234
+ }
235
+
236
+ // TODO: change key to 'foo-bar' if target is undefined?
225
237
 
226
- // Switch root if atomic
227
- if (!((_target = target) != null && _target.set)) root = chain.reduce((acc, key) => acc[key], root);
228
238
  return {
229
239
  root,
230
240
  key,
@@ -455,9 +465,9 @@ function makeId(event) {
455
465
  return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
456
466
  }
457
467
 
458
- /**
459
- * Release pointer captures.
460
- * This is called by releasePointerCapture in the API, and when an object is removed.
468
+ /**
469
+ * Release pointer captures.
470
+ * This is called by releasePointerCapture in the API, and when an object is removed.
461
471
  */
462
472
  function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
463
473
  const captureData = captures.get(obj);
@@ -804,19 +814,19 @@ function createEvents(store) {
804
814
  if (!(instance != null && instance.eventCount)) return;
805
815
  const handlers = instance.handlers;
806
816
 
807
- /*
808
- MAYBE TODO, DELETE IF NOT:
809
- Check if the object is captured, captured events should not have intersects running in parallel
810
- But wouldn't it be better to just replace capturedMap with a single entry?
811
- Also, are we OK with straight up making picking up multiple objects impossible?
812
-
813
- const pointerId = (data as ThreeEvent<PointerEvent>).pointerId
814
- if (pointerId !== undefined) {
815
- const capturedMeshSet = internal.capturedMap.get(pointerId)
816
- if (capturedMeshSet) {
817
- const captured = capturedMeshSet.get(eventObject)
818
- if (captured && captured.localState.stopped) return
819
- }
817
+ /*
818
+ MAYBE TODO, DELETE IF NOT:
819
+ Check if the object is captured, captured events should not have intersects running in parallel
820
+ But wouldn't it be better to just replace capturedMap with a single entry?
821
+ Also, are we OK with straight up making picking up multiple objects impossible?
822
+
823
+ const pointerId = (data as ThreeEvent<PointerEvent>).pointerId
824
+ if (pointerId !== undefined) {
825
+ const capturedMeshSet = internal.capturedMap.get(pointerId)
826
+ if (capturedMeshSet) {
827
+ const captured = capturedMeshSet.get(eventObject)
828
+ if (captured && captured.localState.stopped) return
829
+ }
820
830
  }*/
821
831
 
822
832
  if (isPointerMove) {
@@ -1107,11 +1117,11 @@ const createStore = (invalidate, advance) => {
1107
1117
  return rootStore;
1108
1118
  };
1109
1119
 
1110
- /**
1111
- * Exposes an object's {@link Instance}.
1112
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useInstanceHandle
1113
- *
1114
- * **Note**: this is an escape hatch to react-internal fields. Expect this to change significantly between versions.
1120
+ /**
1121
+ * Exposes an object's {@link Instance}.
1122
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useInstanceHandle
1123
+ *
1124
+ * **Note**: this is an escape hatch to react-internal fields. Expect this to change significantly between versions.
1115
1125
  */
1116
1126
  function useInstanceHandle(ref) {
1117
1127
  const instance = React.useRef(null);
@@ -1119,9 +1129,9 @@ function useInstanceHandle(ref) {
1119
1129
  return instance;
1120
1130
  }
1121
1131
 
1122
- /**
1123
- * Returns the R3F Canvas' Zustand store. Useful for [transient updates](https://github.com/pmndrs/zustand#transient-updates-for-often-occurring-state-changes).
1124
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usestore
1132
+ /**
1133
+ * Returns the R3F Canvas' Zustand store. Useful for [transient updates](https://github.com/pmndrs/zustand#transient-updates-for-often-occurring-state-changes).
1134
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usestore
1125
1135
  */
1126
1136
  function useStore() {
1127
1137
  const store = React.useContext(context);
@@ -1129,18 +1139,18 @@ function useStore() {
1129
1139
  return store;
1130
1140
  }
1131
1141
 
1132
- /**
1133
- * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1134
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1142
+ /**
1143
+ * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1144
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1135
1145
  */
1136
1146
  function useThree(selector = state => state, equalityFn) {
1137
1147
  return useStore()(selector, equalityFn);
1138
1148
  }
1139
1149
 
1140
- /**
1141
- * Executes a callback before render in a shared frame loop.
1142
- * Can order effects with render priority or manually render with a positive priority.
1143
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1150
+ /**
1151
+ * Executes a callback before render in a shared frame loop.
1152
+ * Can order effects with render priority or manually render with a positive priority.
1153
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1144
1154
  */
1145
1155
  function useFrame(callback, renderPriority = 0) {
1146
1156
  const store = useStore();
@@ -1152,9 +1162,9 @@ function useFrame(callback, renderPriority = 0) {
1152
1162
  return null;
1153
1163
  }
1154
1164
 
1155
- /**
1156
- * Returns a node graph of an object with named nodes & materials.
1157
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1165
+ /**
1166
+ * Returns a node graph of an object with named nodes & materials.
1167
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1158
1168
  */
1159
1169
  function useGraph(object) {
1160
1170
  return React.useMemo(() => buildGraph(object), [object]);
@@ -1190,11 +1200,11 @@ function loadingFn(extensions, onProgress) {
1190
1200
  };
1191
1201
  }
1192
1202
 
1193
- /**
1194
- * Synchronously loads and caches assets with a three loader.
1195
- *
1196
- * Note: this hook's caller must be wrapped with `React.Suspense`
1197
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1203
+ /**
1204
+ * Synchronously loads and caches assets with a three loader.
1205
+ *
1206
+ * Note: this hook's caller must be wrapped with `React.Suspense`
1207
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1198
1208
  */
1199
1209
  function useLoader(loader, input, extensions, onProgress) {
1200
1210
  // Use suspense to load async assets
@@ -1206,16 +1216,16 @@ function useLoader(loader, input, extensions, onProgress) {
1206
1216
  return Array.isArray(input) ? results : results[0];
1207
1217
  }
1208
1218
 
1209
- /**
1210
- * Preloads an asset into cache as a side-effect.
1219
+ /**
1220
+ * Preloads an asset into cache as a side-effect.
1211
1221
  */
1212
1222
  useLoader.preload = function (loader, input, extensions) {
1213
1223
  const keys = Array.isArray(input) ? input : [input];
1214
1224
  return preload(loadingFn(extensions), [loader, ...keys]);
1215
1225
  };
1216
1226
 
1217
- /**
1218
- * Removes a loaded asset from cache.
1227
+ /**
1228
+ * Removes a loaded asset from cache.
1219
1229
  */
1220
1230
  useLoader.clear = function (loader, input) {
1221
1231
  const keys = Array.isArray(input) ? input : [input];
@@ -1331,15 +1341,24 @@ function handleContainerEffects(parent, child, beforeChild) {
1331
1341
  } else if (isObject3D(child.object) && isObject3D(parent.object)) {
1332
1342
  const childIndex = parent.object.children.indexOf(beforeChild == null ? void 0 : beforeChild.object);
1333
1343
  if (beforeChild && childIndex !== -1) {
1334
- child.object.parent = parent.object;
1335
- parent.object.children.splice(childIndex, 0, child.object);
1336
- child.object.dispatchEvent({
1337
- type: 'added'
1338
- });
1339
- parent.object.dispatchEvent({
1340
- type: 'childadded',
1341
- child: child.object
1342
- });
1344
+ // If the child is already in the parent's children array, move it to the new position
1345
+ // Otherwise, just insert it at the target position
1346
+ const existingIndex = parent.object.children.indexOf(child.object);
1347
+ if (existingIndex !== -1) {
1348
+ parent.object.children.splice(existingIndex, 1);
1349
+ const adjustedIndex = existingIndex < childIndex ? childIndex - 1 : childIndex;
1350
+ parent.object.children.splice(adjustedIndex, 0, child.object);
1351
+ } else {
1352
+ child.object.parent = parent.object;
1353
+ parent.object.children.splice(childIndex, 0, child.object);
1354
+ child.object.dispatchEvent({
1355
+ type: 'added'
1356
+ });
1357
+ parent.object.dispatchEvent({
1358
+ type: 'childadded',
1359
+ child: child.object
1360
+ });
1361
+ }
1343
1362
  } else {
1344
1363
  parent.object.add(child.object);
1345
1364
  }
@@ -2040,10 +2059,10 @@ function Portal({
2040
2059
  children,
2041
2060
  container
2042
2061
  }) {
2043
- /** This has to be a component because it would not be able to call useThree/useStore otherwise since
2044
- * if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
2045
- * the "R3F hooks can only be used within the Canvas component!" warning:
2046
- * <Canvas>
2062
+ /** This has to be a component because it would not be able to call useThree/useStore otherwise since
2063
+ * if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
2064
+ * the "R3F hooks can only be used within the Canvas component!" warning:
2065
+ * <Canvas>
2047
2066
  * {createPortal(...)} */
2048
2067
  const {
2049
2068
  events,
@@ -2135,21 +2154,21 @@ const globalEffects = new Set();
2135
2154
  const globalAfterEffects = new Set();
2136
2155
  const globalTailEffects = new Set();
2137
2156
 
2138
- /**
2139
- * Adds a global render callback which is called each frame.
2140
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
2157
+ /**
2158
+ * Adds a global render callback which is called each frame.
2159
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
2141
2160
  */
2142
2161
  const addEffect = callback => createSubs(callback, globalEffects);
2143
2162
 
2144
- /**
2145
- * Adds a global after-render callback which is called each frame.
2146
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
2163
+ /**
2164
+ * Adds a global after-render callback which is called each frame.
2165
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
2147
2166
  */
2148
2167
  const addAfterEffect = callback => createSubs(callback, globalAfterEffects);
2149
2168
 
2150
- /**
2151
- * Adds a global callback which is called when rendering stops.
2152
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
2169
+ /**
2170
+ * Adds a global callback which is called when rendering stops.
2171
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
2153
2172
  */
2154
2173
  const addTail = callback => createSubs(callback, globalTailEffects);
2155
2174
  function run(effects, timestamp) {
@@ -2237,9 +2256,9 @@ function loop(timestamp) {
2237
2256
  }
2238
2257
  }
2239
2258
 
2240
- /**
2241
- * Invalidates the view, requesting a frame to be rendered. Will globally invalidate unless passed a root's state.
2242
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#invalidate
2259
+ /**
2260
+ * Invalidates the view, requesting a frame to be rendered. Will globally invalidate unless passed a root's state.
2261
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#invalidate
2243
2262
  */
2244
2263
  function invalidate(state, frames = 1) {
2245
2264
  var _state$gl$xr2;
@@ -2266,9 +2285,9 @@ function invalidate(state, frames = 1) {
2266
2285
  }
2267
2286
  }
2268
2287
 
2269
- /**
2270
- * Advances the frameloop and runs render effects, useful for when manually rendering via `frameloop="never"`.
2271
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#advance
2288
+ /**
2289
+ * Advances the frameloop and runs render effects, useful for when manually rendering via `frameloop="never"`.
2290
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#advance
2272
2291
  */
2273
2292
  function advance(timestamp, runGlobalEffects = true, state, frame) {
2274
2293
  if (runGlobalEffects) flushGlobalEffects('before', timestamp);