@react-three/fiber 8.0.22 → 8.0.25

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.
@@ -1,9 +1,9 @@
1
- import * as React from 'react';
2
- import type { Options as ResizeOptions } from 'react-use-measure';
3
- import { RenderProps } from '../core';
4
- export interface Props extends Omit<RenderProps<HTMLCanvasElement>, 'size'>, React.HTMLAttributes<HTMLDivElement> {
5
- children: React.ReactNode;
6
- fallback?: React.ReactNode;
7
- resize?: ResizeOptions;
8
- }
9
- export declare const Canvas: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLCanvasElement>>;
1
+ import * as React from 'react';
2
+ import type { Options as ResizeOptions } from 'react-use-measure';
3
+ import { RenderProps } from '../core';
4
+ export interface Props extends Omit<RenderProps<HTMLCanvasElement>, 'size'>, React.HTMLAttributes<HTMLDivElement> {
5
+ children: React.ReactNode;
6
+ fallback?: React.ReactNode;
7
+ resize?: ResizeOptions;
8
+ }
9
+ export declare const Canvas: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLCanvasElement>>;
@@ -1,4 +1,4 @@
1
- import { UseBoundStore } from 'zustand';
2
- import { RootState } from '../core/store';
3
- import { EventManager } from '../core/events';
4
- export declare function createPointerEvents(store: UseBoundStore<RootState>): EventManager<HTMLElement>;
1
+ import { UseBoundStore } from 'zustand';
2
+ import { RootState } from '../core/store';
3
+ import { EventManager } from '../core/events';
4
+ export declare function createPointerEvents(store: UseBoundStore<RootState>): EventManager<HTMLElement>;
@@ -173,7 +173,7 @@ function prepare(object, state) {
173
173
  eventCount: 0,
174
174
  handlers: {},
175
175
  objects: [],
176
- parents: [],
176
+ parent: null,
177
177
  ...state
178
178
  };
179
179
  }
@@ -287,7 +287,7 @@ function diffProps(instance, {
287
287
  } // This function applies a set of changes to the instance
288
288
 
289
289
  function applyProps$1(instance, data) {
290
- var _instance$__r3f3, _root$getState, _localState$parents;
290
+ var _instance$__r3f3, _root$getState;
291
291
 
292
292
  // Filter equals, events and reserved props
293
293
  const localState = (_instance$__r3f3 = instance.__r3f) != null ? _instance$__r3f3 : {};
@@ -378,7 +378,7 @@ function applyProps$1(instance, data) {
378
378
  invalidateInstance(instance);
379
379
  });
380
380
 
381
- if ((_localState$parents = localState.parents) != null && _localState$parents.length && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
381
+ if (localState.parent && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
382
382
  // Pre-emptively remove the instance from the interaction manager
383
383
  const index = rootState.internal.interaction.indexOf(instance);
384
384
  if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
@@ -871,7 +871,7 @@ function createRenderer(roots, getEventPriority) {
871
871
  if (type === 'primitive') {
872
872
  if (props.object === undefined) throw `Primitives without 'object' are invalid!`;
873
873
  const object = props.object;
874
- instance = prepare(object, { ...object.__r3f,
874
+ instance = prepare(object, {
875
875
  type,
876
876
  root,
877
877
  attach,
@@ -913,9 +913,10 @@ function createRenderer(roots, getEventPriority) {
913
913
  if (child) {
914
914
  var _child$__r3f, _parentInstance$__r3f;
915
915
 
916
- // The attach attribute implies that the object attaches itself on the parent.
917
- // That is handled at commit to avoid duplication during Suspense
918
- if (!((_child$__r3f = child.__r3f) != null && _child$__r3f.attach) && child.isObject3D && parentInstance.isObject3D) {
916
+ // The attach attribute implies that the object attaches itself on the parent
917
+ if ((_child$__r3f = child.__r3f) != null && _child$__r3f.attach) {
918
+ attach(parentInstance, child, child.__r3f.attach);
919
+ } else if (child.isObject3D && parentInstance.isObject3D) {
919
920
  // add in the usual parent-child way
920
921
  parentInstance.add(child);
921
922
  added = true;
@@ -925,9 +926,7 @@ function createRenderer(roots, getEventPriority) {
925
926
 
926
927
  if (!added) (_parentInstance$__r3f = parentInstance.__r3f) == null ? void 0 : _parentInstance$__r3f.objects.push(child);
927
928
  if (!child.__r3f) prepare(child, {});
928
-
929
- child.__r3f.parents.push(parentInstance);
930
-
929
+ child.__r3f.parent = parentInstance;
931
930
  updateInstance(child);
932
931
  invalidateInstance(child);
933
932
  }
@@ -939,7 +938,9 @@ function createRenderer(roots, getEventPriority) {
939
938
  if (child) {
940
939
  var _child$__r3f2, _parentInstance$__r3f2;
941
940
 
942
- if (!((_child$__r3f2 = child.__r3f) != null && _child$__r3f2.attach) && child.isObject3D && parentInstance.isObject3D) {
941
+ if ((_child$__r3f2 = child.__r3f) != null && _child$__r3f2.attach) {
942
+ attach(parentInstance, child, child.__r3f.attach);
943
+ } else if (child.isObject3D && parentInstance.isObject3D) {
943
944
  child.parent = parentInstance;
944
945
  child.dispatchEvent({
945
946
  type: 'added'
@@ -952,9 +953,7 @@ function createRenderer(roots, getEventPriority) {
952
953
 
953
954
  if (!added) (_parentInstance$__r3f2 = parentInstance.__r3f) == null ? void 0 : _parentInstance$__r3f2.objects.push(child);
954
955
  if (!child.__r3f) prepare(child, {});
955
-
956
- child.__r3f.parents.push(parentInstance);
957
-
956
+ child.__r3f.parent = parentInstance;
958
957
  updateInstance(child);
959
958
  invalidateInstance(child);
960
959
  }
@@ -969,7 +968,7 @@ function createRenderer(roots, getEventPriority) {
969
968
  var _parentInstance$__r3f3, _child$__r3f3, _child$__r3f5;
970
969
 
971
970
  // Clear the parent reference
972
- if (child.__r3f) child.__r3f.parents = child.__r3f.parents.filter(parent => parent !== parentInstance); // Remove child from the parents objects
971
+ if (child.__r3f) child.__r3f.parent = null; // Remove child from the parents objects
973
972
 
974
973
  if ((_parentInstance$__r3f3 = parentInstance.__r3f) != null && _parentInstance$__r3f3.objects) parentInstance.__r3f.objects = parentInstance.__r3f.objects.filter(x => x !== child); // Remove attachment
975
974
 
@@ -1030,10 +1029,10 @@ function createRenderer(roots, getEventPriority) {
1030
1029
  }
1031
1030
 
1032
1031
  function switchInstance(instance, type, newProps, fiber) {
1033
- var _instance$__r3f, _newInstance$__r3f;
1032
+ var _instance$__r3f;
1034
1033
 
1035
- const parents = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parents;
1036
- if (!(parents != null && parents.length)) return;
1034
+ const parent = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parent;
1035
+ if (!parent) return;
1037
1036
  const newInstance = createInstance(type, newProps, instance.__r3f.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
1038
1037
  // When args change the instance has to be re-constructed, which then
1039
1038
  // forces r3f to re-parent the children and non-scene objects
@@ -1042,34 +1041,18 @@ function createRenderer(roots, getEventPriority) {
1042
1041
  if (type !== 'primitive' && instance.children) {
1043
1042
  instance.children.forEach(child => appendChild(newInstance, child));
1044
1043
  instance.children = [];
1045
- } // Copy over child attachments
1046
-
1047
-
1048
- for (const child of instance.__r3f.objects) {
1049
- appendChild(newInstance, child);
1050
- detach(instance, child, child.__r3f.attach);
1051
- attach(newInstance, child, child.__r3f.attach);
1052
1044
  }
1053
1045
 
1054
- instance.__r3f.objects = [];
1055
-
1056
- for (const parent of parents) {
1057
- removeChild(parent, instance);
1058
- appendChild(parent, newInstance);
1059
- } // Re-bind event handlers
1046
+ instance.__r3f.objects.forEach(child => appendChild(newInstance, child));
1060
1047
 
1048
+ instance.__r3f.objects = [];
1049
+ removeChild(parent, instance);
1050
+ appendChild(parent, newInstance); // Re-bind event handlers
1061
1051
 
1062
1052
  if (newInstance.raycast && newInstance.__r3f.eventCount) {
1063
1053
  const rootState = newInstance.__r3f.root.getState();
1064
1054
 
1065
1055
  rootState.internal.interaction.push(newInstance);
1066
- } // Attach instance to parent
1067
-
1068
-
1069
- if ((_newInstance$__r3f = newInstance.__r3f) != null && _newInstance$__r3f.attach) {
1070
- for (const parent of parents) {
1071
- attach(parent, newInstance, newInstance.__r3f.attach);
1072
- }
1073
1056
  } // This evil hack switches the react-internal fiber node
1074
1057
  [fiber, fiber.alternate].forEach(fiber => {
1075
1058
  if (fiber !== null) {
@@ -1110,7 +1093,7 @@ function createRenderer(roots, getEventPriority) {
1110
1093
  const localState = (_instance$__r3f2 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f2 : {}; // https://github.com/facebook/react/issues/20271
1111
1094
  // Returning true will trigger commitMount
1112
1095
 
1113
- return !!localState.handlers || !!localState.attach;
1096
+ return !!localState.handlers;
1114
1097
  },
1115
1098
 
1116
1099
  prepareUpdate(instance, type, oldProps, newProps) {
@@ -1156,13 +1139,6 @@ function createRenderer(roots, getEventPriority) {
1156
1139
 
1157
1140
  if (instance.raycast && localState.handlers && localState.eventCount) {
1158
1141
  instance.__r3f.root.getState().internal.interaction.push(instance);
1159
- } // The attach attribute implies that the object attaches itself on the parent
1160
-
1161
-
1162
- if (localState.attach) {
1163
- for (const parent of localState.parents) {
1164
- attach(parent, instance, localState.attach);
1165
- }
1166
1142
  }
1167
1143
  },
1168
1144
 
@@ -1176,11 +1152,27 @@ function createRenderer(roots, getEventPriority) {
1176
1152
  detachDeletedInstance: () => {},
1177
1153
 
1178
1154
  hideInstance(instance) {
1155
+ var _instance$__r3f4;
1156
+
1157
+ // Deatch while the instance is hidden
1158
+ const {
1159
+ attach: type,
1160
+ parent
1161
+ } = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
1162
+ if (type && parent) detach(parent, instance, type);
1179
1163
  if (instance.isObject3D) instance.visible = false;
1180
1164
  invalidateInstance(instance);
1181
1165
  },
1182
1166
 
1183
1167
  unhideInstance(instance, props) {
1168
+ var _instance$__r3f5;
1169
+
1170
+ // Re-attach when the instance is unhidden
1171
+ const {
1172
+ attach: type,
1173
+ parent
1174
+ } = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
1175
+ if (type && parent) attach(parent, instance, type);
1184
1176
  if (instance.isObject3D && props.visible == null || props.visible) instance.visible = true;
1185
1177
  invalidateInstance(instance);
1186
1178
  },
@@ -1417,6 +1409,23 @@ const createStore = (invalidate, advance) => {
1417
1409
  oldSize = size;
1418
1410
  oldDpr = viewport.dpr;
1419
1411
  }
1412
+ }); // Update viewport once the camera changes
1413
+
1414
+ let oldCamera = state.camera;
1415
+ rootState.subscribe(() => {
1416
+ const {
1417
+ camera,
1418
+ set
1419
+ } = rootState.getState();
1420
+
1421
+ if (camera !== oldCamera) {
1422
+ set(state => ({
1423
+ viewport: { ...state.viewport,
1424
+ ...state.viewport.getCurrentViewport(camera)
1425
+ }
1426
+ }));
1427
+ oldCamera = camera;
1428
+ }
1420
1429
  }); // Invalidate on any change
1421
1430
 
1422
1431
  rootState.subscribe(state => invalidate(state)); // Return root state
@@ -1605,13 +1614,14 @@ function loadingFn(extensions, onProgress) {
1605
1614
  }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1606
1615
  };
1607
1616
  }
1608
-
1609
1617
  /**
1610
1618
  * Synchronously loads and caches assets with a three loader.
1611
1619
  *
1612
1620
  * Note: this hook's caller must be wrapped with `React.Suspense`
1613
1621
  * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1614
1622
  */
1623
+
1624
+
1615
1625
  function useLoader(Proto, input, extensions, onProgress) {
1616
1626
  // Use suspense to load async assets
1617
1627
  const keys = Array.isArray(input) ? input : [input];
@@ -146,7 +146,7 @@ function prepare(object, state) {
146
146
  eventCount: 0,
147
147
  handlers: {},
148
148
  objects: [],
149
- parents: [],
149
+ parent: null,
150
150
  ...state
151
151
  };
152
152
  }
@@ -260,7 +260,7 @@ function diffProps(instance, {
260
260
  } // This function applies a set of changes to the instance
261
261
 
262
262
  function applyProps$1(instance, data) {
263
- var _instance$__r3f3, _root$getState, _localState$parents;
263
+ var _instance$__r3f3, _root$getState;
264
264
 
265
265
  // Filter equals, events and reserved props
266
266
  const localState = (_instance$__r3f3 = instance.__r3f) != null ? _instance$__r3f3 : {};
@@ -351,7 +351,7 @@ function applyProps$1(instance, data) {
351
351
  invalidateInstance(instance);
352
352
  });
353
353
 
354
- if ((_localState$parents = localState.parents) != null && _localState$parents.length && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
354
+ if (localState.parent && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
355
355
  // Pre-emptively remove the instance from the interaction manager
356
356
  const index = rootState.internal.interaction.indexOf(instance);
357
357
  if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
@@ -844,7 +844,7 @@ function createRenderer(roots, getEventPriority) {
844
844
  if (type === 'primitive') {
845
845
  if (props.object === undefined) throw `Primitives without 'object' are invalid!`;
846
846
  const object = props.object;
847
- instance = prepare(object, { ...object.__r3f,
847
+ instance = prepare(object, {
848
848
  type,
849
849
  root,
850
850
  attach,
@@ -886,9 +886,10 @@ function createRenderer(roots, getEventPriority) {
886
886
  if (child) {
887
887
  var _child$__r3f, _parentInstance$__r3f;
888
888
 
889
- // The attach attribute implies that the object attaches itself on the parent.
890
- // That is handled at commit to avoid duplication during Suspense
891
- if (!((_child$__r3f = child.__r3f) != null && _child$__r3f.attach) && child.isObject3D && parentInstance.isObject3D) {
889
+ // The attach attribute implies that the object attaches itself on the parent
890
+ if ((_child$__r3f = child.__r3f) != null && _child$__r3f.attach) {
891
+ attach(parentInstance, child, child.__r3f.attach);
892
+ } else if (child.isObject3D && parentInstance.isObject3D) {
892
893
  // add in the usual parent-child way
893
894
  parentInstance.add(child);
894
895
  added = true;
@@ -898,9 +899,7 @@ function createRenderer(roots, getEventPriority) {
898
899
 
899
900
  if (!added) (_parentInstance$__r3f = parentInstance.__r3f) == null ? void 0 : _parentInstance$__r3f.objects.push(child);
900
901
  if (!child.__r3f) prepare(child, {});
901
-
902
- child.__r3f.parents.push(parentInstance);
903
-
902
+ child.__r3f.parent = parentInstance;
904
903
  updateInstance(child);
905
904
  invalidateInstance(child);
906
905
  }
@@ -912,7 +911,9 @@ function createRenderer(roots, getEventPriority) {
912
911
  if (child) {
913
912
  var _child$__r3f2, _parentInstance$__r3f2;
914
913
 
915
- if (!((_child$__r3f2 = child.__r3f) != null && _child$__r3f2.attach) && child.isObject3D && parentInstance.isObject3D) {
914
+ if ((_child$__r3f2 = child.__r3f) != null && _child$__r3f2.attach) {
915
+ attach(parentInstance, child, child.__r3f.attach);
916
+ } else if (child.isObject3D && parentInstance.isObject3D) {
916
917
  child.parent = parentInstance;
917
918
  child.dispatchEvent({
918
919
  type: 'added'
@@ -925,9 +926,7 @@ function createRenderer(roots, getEventPriority) {
925
926
 
926
927
  if (!added) (_parentInstance$__r3f2 = parentInstance.__r3f) == null ? void 0 : _parentInstance$__r3f2.objects.push(child);
927
928
  if (!child.__r3f) prepare(child, {});
928
-
929
- child.__r3f.parents.push(parentInstance);
930
-
929
+ child.__r3f.parent = parentInstance;
931
930
  updateInstance(child);
932
931
  invalidateInstance(child);
933
932
  }
@@ -942,7 +941,7 @@ function createRenderer(roots, getEventPriority) {
942
941
  var _parentInstance$__r3f3, _child$__r3f3, _child$__r3f5;
943
942
 
944
943
  // Clear the parent reference
945
- if (child.__r3f) child.__r3f.parents = child.__r3f.parents.filter(parent => parent !== parentInstance); // Remove child from the parents objects
944
+ if (child.__r3f) child.__r3f.parent = null; // Remove child from the parents objects
946
945
 
947
946
  if ((_parentInstance$__r3f3 = parentInstance.__r3f) != null && _parentInstance$__r3f3.objects) parentInstance.__r3f.objects = parentInstance.__r3f.objects.filter(x => x !== child); // Remove attachment
948
947
 
@@ -1003,10 +1002,10 @@ function createRenderer(roots, getEventPriority) {
1003
1002
  }
1004
1003
 
1005
1004
  function switchInstance(instance, type, newProps, fiber) {
1006
- var _instance$__r3f, _newInstance$__r3f;
1005
+ var _instance$__r3f;
1007
1006
 
1008
- const parents = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parents;
1009
- if (!(parents != null && parents.length)) return;
1007
+ const parent = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parent;
1008
+ if (!parent) return;
1010
1009
  const newInstance = createInstance(type, newProps, instance.__r3f.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
1011
1010
  // When args change the instance has to be re-constructed, which then
1012
1011
  // forces r3f to re-parent the children and non-scene objects
@@ -1015,34 +1014,18 @@ function createRenderer(roots, getEventPriority) {
1015
1014
  if (type !== 'primitive' && instance.children) {
1016
1015
  instance.children.forEach(child => appendChild(newInstance, child));
1017
1016
  instance.children = [];
1018
- } // Copy over child attachments
1019
-
1020
-
1021
- for (const child of instance.__r3f.objects) {
1022
- appendChild(newInstance, child);
1023
- detach(instance, child, child.__r3f.attach);
1024
- attach(newInstance, child, child.__r3f.attach);
1025
1017
  }
1026
1018
 
1027
- instance.__r3f.objects = [];
1028
-
1029
- for (const parent of parents) {
1030
- removeChild(parent, instance);
1031
- appendChild(parent, newInstance);
1032
- } // Re-bind event handlers
1019
+ instance.__r3f.objects.forEach(child => appendChild(newInstance, child));
1033
1020
 
1021
+ instance.__r3f.objects = [];
1022
+ removeChild(parent, instance);
1023
+ appendChild(parent, newInstance); // Re-bind event handlers
1034
1024
 
1035
1025
  if (newInstance.raycast && newInstance.__r3f.eventCount) {
1036
1026
  const rootState = newInstance.__r3f.root.getState();
1037
1027
 
1038
1028
  rootState.internal.interaction.push(newInstance);
1039
- } // Attach instance to parent
1040
-
1041
-
1042
- if ((_newInstance$__r3f = newInstance.__r3f) != null && _newInstance$__r3f.attach) {
1043
- for (const parent of parents) {
1044
- attach(parent, newInstance, newInstance.__r3f.attach);
1045
- }
1046
1029
  } // This evil hack switches the react-internal fiber node
1047
1030
  [fiber, fiber.alternate].forEach(fiber => {
1048
1031
  if (fiber !== null) {
@@ -1083,7 +1066,7 @@ function createRenderer(roots, getEventPriority) {
1083
1066
  const localState = (_instance$__r3f2 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f2 : {}; // https://github.com/facebook/react/issues/20271
1084
1067
  // Returning true will trigger commitMount
1085
1068
 
1086
- return !!localState.handlers || !!localState.attach;
1069
+ return !!localState.handlers;
1087
1070
  },
1088
1071
 
1089
1072
  prepareUpdate(instance, type, oldProps, newProps) {
@@ -1129,13 +1112,6 @@ function createRenderer(roots, getEventPriority) {
1129
1112
 
1130
1113
  if (instance.raycast && localState.handlers && localState.eventCount) {
1131
1114
  instance.__r3f.root.getState().internal.interaction.push(instance);
1132
- } // The attach attribute implies that the object attaches itself on the parent
1133
-
1134
-
1135
- if (localState.attach) {
1136
- for (const parent of localState.parents) {
1137
- attach(parent, instance, localState.attach);
1138
- }
1139
1115
  }
1140
1116
  },
1141
1117
 
@@ -1149,11 +1125,27 @@ function createRenderer(roots, getEventPriority) {
1149
1125
  detachDeletedInstance: () => {},
1150
1126
 
1151
1127
  hideInstance(instance) {
1128
+ var _instance$__r3f4;
1129
+
1130
+ // Deatch while the instance is hidden
1131
+ const {
1132
+ attach: type,
1133
+ parent
1134
+ } = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
1135
+ if (type && parent) detach(parent, instance, type);
1152
1136
  if (instance.isObject3D) instance.visible = false;
1153
1137
  invalidateInstance(instance);
1154
1138
  },
1155
1139
 
1156
1140
  unhideInstance(instance, props) {
1141
+ var _instance$__r3f5;
1142
+
1143
+ // Re-attach when the instance is unhidden
1144
+ const {
1145
+ attach: type,
1146
+ parent
1147
+ } = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
1148
+ if (type && parent) attach(parent, instance, type);
1157
1149
  if (instance.isObject3D && props.visible == null || props.visible) instance.visible = true;
1158
1150
  invalidateInstance(instance);
1159
1151
  },
@@ -1390,6 +1382,23 @@ const createStore = (invalidate, advance) => {
1390
1382
  oldSize = size;
1391
1383
  oldDpr = viewport.dpr;
1392
1384
  }
1385
+ }); // Update viewport once the camera changes
1386
+
1387
+ let oldCamera = state.camera;
1388
+ rootState.subscribe(() => {
1389
+ const {
1390
+ camera,
1391
+ set
1392
+ } = rootState.getState();
1393
+
1394
+ if (camera !== oldCamera) {
1395
+ set(state => ({
1396
+ viewport: { ...state.viewport,
1397
+ ...state.viewport.getCurrentViewport(camera)
1398
+ }
1399
+ }));
1400
+ oldCamera = camera;
1401
+ }
1393
1402
  }); // Invalidate on any change
1394
1403
 
1395
1404
  rootState.subscribe(state => invalidate(state)); // Return root state
@@ -1578,13 +1587,14 @@ function loadingFn(extensions, onProgress) {
1578
1587
  }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1579
1588
  };
1580
1589
  }
1581
-
1582
1590
  /**
1583
1591
  * Synchronously loads and caches assets with a three loader.
1584
1592
  *
1585
1593
  * Note: this hook's caller must be wrapped with `React.Suspense`
1586
1594
  * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1587
1595
  */
1596
+
1597
+
1588
1598
  function useLoader(Proto, input, extensions, onProgress) {
1589
1599
  // Use suspense to load async assets
1590
1600
  const keys = Array.isArray(input) ? input : [input];