@react-three/fiber 9.6.0 → 9.7.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @react-three/fiber
2
2
 
3
+ ## 9.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c340195e7129d6b244a9eb11c0c10573954d03ef: Match React DOM event priorities and microtask scheduling so reconciler updates flush with consistent priority and timing.
8
+
9
+ ### Patch Changes
10
+
11
+ - c340195e7129d6b244a9eb11c0c10573954d03ef: Harden internal instance synchronization after keyed reorders and batched reconstruction, and correctly reset pierced props.
12
+
13
+ ## 9.6.1
14
+
15
+ ### Patch Changes
16
+
17
+ - b645741874486417727ea75a0704d48e9f21d623: fix: Seamlessly transfer interactivity state when swapping instances
18
+
3
19
  ## 9.6.0
4
20
 
5
21
  ### Minor Changes
@@ -86,6 +86,8 @@ export interface PointerCaptureTarget {
86
86
  intersection: Intersection;
87
87
  target: Element;
88
88
  }
89
+ /** This function transfers all interactivity state from one object instance to another. Used when swapping instances due to reconstruction. */
90
+ export declare function swapInteractivity(store: RootStore, object: THREE.Object3D, newObject: THREE.Object3D): void;
89
91
  export declare function removeInteractivity(store: RootStore, object: THREE.Object3D): void;
90
92
  export declare function createEvents(store: RootStore): {
91
93
  handlePointer: (name: string) => (event: DomEvent) => void;
@@ -3,7 +3,7 @@ import React__default from 'react';
3
3
  import * as THREE from 'three';
4
4
  import { createWithEqualityFn } from 'zustand/traditional';
5
5
  import { suspend, preload, clear } from 'suspend-react';
6
- import Tb, { unstable_scheduleCallback, unstable_IdlePriority } from 'scheduler';
6
+ import Tb, { unstable_getCurrentPriorityLevel, unstable_IdlePriority, unstable_LowPriority, unstable_NormalPriority, unstable_UserBlockingPriority, unstable_ImmediatePriority, unstable_scheduleCallback } from 'scheduler';
7
7
  import { jsx, Fragment } from 'react/jsx-runtime';
8
8
  import { useFiber, useContextBridge, traverseFiber } from 'its-fine';
9
9
 
@@ -355,10 +355,10 @@ function diffProps(instance, newProps) {
355
355
  if (root.constructor && root.constructor.length === 0) {
356
356
  // create a blank slate of the instance and copy the particular parameter.
357
357
  const ctor = getMemoizedPrototype(root);
358
- if (!is.und(ctor)) changedProps[key] = ctor[key];
358
+ if (!is.und(ctor)) changedProps[prop] = ctor[key];
359
359
  } else {
360
360
  // instance does not have constructor, just set it to 0
361
- changedProps[key] = 0;
361
+ changedProps[prop] = 0;
362
362
  }
363
363
  }
364
364
  return changedProps;
@@ -517,6 +517,37 @@ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
517
517
  }
518
518
  }
519
519
  }
520
+
521
+ /** This function transfers all interactivity state from one object instance to another. Used when swapping instances due to reconstruction. */
522
+ function swapInteractivity(store, object, newObject) {
523
+ const {
524
+ internal
525
+ } = store.getState();
526
+ for (let i = 0; i < internal.interaction.length; i++) {
527
+ if (internal.interaction[i] === object) internal.interaction[i] = newObject;
528
+ }
529
+ for (let i = 0; i < internal.initialHits.length; i++) {
530
+ if (internal.initialHits[i] === object) internal.initialHits[i] = newObject;
531
+ }
532
+ internal.hovered.forEach((value, key) => {
533
+ if (value.eventObject === object || value.object === object) {
534
+ internal.hovered.delete(key);
535
+ const next = {
536
+ ...value,
537
+ eventObject: value.eventObject === object ? newObject : value.eventObject,
538
+ object: value.object === object ? newObject : value.object
539
+ };
540
+ internal.hovered.set(makeId(next), next);
541
+ }
542
+ });
543
+ internal.capturedMap.forEach(captures => {
544
+ const captureData = captures.get(object);
545
+ if (captureData) {
546
+ captures.delete(object);
547
+ captures.set(newObject, captureData);
548
+ }
549
+ });
550
+ }
520
551
  function removeInteractivity(store, object) {
521
552
  const {
522
553
  internal
@@ -1280,11 +1311,12 @@ useLoader.clear = function (loader, input) {
1280
1311
  */const t = 1,
1281
1312
  o = 8,
1282
1313
  r = 32,
1283
- e = 2;
1314
+ e = 2,
1315
+ i$1 = 268435456;
1284
1316
 
1285
1317
  var packageData = {
1286
1318
  name: "@react-three/fiber",
1287
- version: "9.6.0",
1319
+ version: "9.7.0",
1288
1320
  description: "A React renderer for Threejs",
1289
1321
  keywords: [
1290
1322
  "react",
@@ -15120,6 +15152,12 @@ function handleContainerEffects(parent, child, beforeChild) {
15120
15152
  function appendChild(parent, child) {
15121
15153
  if (!child) return;
15122
15154
 
15155
+ // Move an existing child instead of duplicating it
15156
+ if (child.parent === parent) {
15157
+ const childIndex = parent.children.indexOf(child);
15158
+ if (childIndex !== -1) parent.children.splice(childIndex, 1);
15159
+ }
15160
+
15123
15161
  // Link instances
15124
15162
  child.parent = parent;
15125
15163
  parent.children.push(child);
@@ -15130,6 +15168,12 @@ function appendChild(parent, child) {
15130
15168
  function insertBefore(parent, child, beforeChild) {
15131
15169
  if (!child || !beforeChild) return;
15132
15170
 
15171
+ // Move an existing child instead of duplicating it.
15172
+ if (child.parent === parent) {
15173
+ const childIndex = parent.children.indexOf(child);
15174
+ if (childIndex !== -1) parent.children.splice(childIndex, 1);
15175
+ }
15176
+
15133
15177
  // Link instances
15134
15178
  child.parent = parent;
15135
15179
  const childIndex = parent.children.indexOf(beforeChild);
@@ -15210,7 +15254,15 @@ function setFiberRef(fiber, publicInstance) {
15210
15254
  }
15211
15255
  }
15212
15256
  const reconstructed = [];
15213
- function swapInstances() {
15257
+ function flushReconstructedInstances() {
15258
+ if (reconstructed.length === 0) return;
15259
+ try {
15260
+ swapReconstructedInstances();
15261
+ } finally {
15262
+ reconstructed.length = 0;
15263
+ }
15264
+ }
15265
+ function swapReconstructedInstances() {
15214
15266
  // Detach instance
15215
15267
  for (const [instance] of reconstructed) {
15216
15268
  const parent = instance.parent;
@@ -15250,11 +15302,11 @@ function swapInstances() {
15250
15302
  const target = catalogue[toPascalCase(instance.type)];
15251
15303
 
15252
15304
  // Create object
15305
+ const prevObject = instance.object;
15253
15306
  instance.object = (_instance$props$objec = instance.props.object) != null ? _instance$props$objec : new target(...((_instance$props$args = instance.props.args) != null ? _instance$props$args : []));
15254
15307
  instance.object.__r3f = instance;
15255
15308
  setFiberRef(fiber, instance.object);
15256
-
15257
- // Set initial props
15309
+ swapInteractivity(findInitialRoot(instance), prevObject, instance.object);
15258
15310
  applyProps(instance.object, instance.props);
15259
15311
  if (instance.props.attach) {
15260
15312
  attach(parent, instance);
@@ -15273,7 +15325,6 @@ function swapInstances() {
15273
15325
  invalidateInstance(instance);
15274
15326
  }
15275
15327
  }
15276
- reconstructed.length = 0;
15277
15328
  }
15278
15329
 
15279
15330
  // Don't handle text instances, make it no-op
@@ -15281,9 +15332,112 @@ const handleTextInstance = () => {};
15281
15332
  const NO_CONTEXT = {};
15282
15333
  let currentUpdatePriority = NoEventPriority;
15283
15334
 
15284
- // https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberFlags.js
15285
- const NoFlags = 0;
15286
- const Update = 4;
15335
+ // Mirrors react-dom's getEventPriority for parity with events outside of React
15336
+ // https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/events/ReactDOMEventListener.js
15337
+ function getEventPriority(type) {
15338
+ switch (type) {
15339
+ case 'beforetoggle':
15340
+ case 'cancel':
15341
+ case 'click':
15342
+ case 'close':
15343
+ case 'contextmenu':
15344
+ case 'copy':
15345
+ case 'cut':
15346
+ case 'auxclick':
15347
+ case 'dblclick':
15348
+ case 'dragend':
15349
+ case 'dragstart':
15350
+ case 'drop':
15351
+ case 'focusin':
15352
+ case 'focusout':
15353
+ case 'input':
15354
+ case 'invalid':
15355
+ case 'keydown':
15356
+ case 'keypress':
15357
+ case 'keyup':
15358
+ case 'mousedown':
15359
+ case 'mouseup':
15360
+ case 'paste':
15361
+ case 'pause':
15362
+ case 'play':
15363
+ case 'pointercancel':
15364
+ case 'pointerdown':
15365
+ case 'pointerup':
15366
+ case 'ratechange':
15367
+ case 'reset':
15368
+ case 'resize':
15369
+ case 'seeked':
15370
+ case 'submit':
15371
+ case 'touchcancel':
15372
+ case 'touchend':
15373
+ case 'touchstart':
15374
+ case 'volumechange':
15375
+ case 'change':
15376
+ case 'selectionchange':
15377
+ case 'compositionstart':
15378
+ case 'compositionend':
15379
+ case 'compositionupdate':
15380
+ case 'beforeinput':
15381
+ case 'blur':
15382
+ case 'fullscreenchange':
15383
+ case 'focus':
15384
+ case 'hashchange':
15385
+ case 'popstate':
15386
+ case 'select':
15387
+ case 'selectstart':
15388
+ return e;
15389
+ case 'drag':
15390
+ case 'dragenter':
15391
+ case 'dragexit':
15392
+ case 'dragleave':
15393
+ case 'dragover':
15394
+ case 'mousemove':
15395
+ case 'mouseout':
15396
+ case 'mouseover':
15397
+ case 'pointermove':
15398
+ case 'pointerout':
15399
+ case 'pointerover':
15400
+ case 'scroll':
15401
+ case 'touchmove':
15402
+ case 'wheel':
15403
+ case 'mouseenter':
15404
+ case 'mouseleave':
15405
+ case 'pointerenter':
15406
+ case 'pointerleave':
15407
+ return o;
15408
+ case 'message':
15409
+ {
15410
+ switch (unstable_getCurrentPriorityLevel()) {
15411
+ case unstable_ImmediatePriority:
15412
+ return e;
15413
+ case unstable_UserBlockingPriority:
15414
+ return o;
15415
+ case unstable_NormalPriority:
15416
+ case unstable_LowPriority:
15417
+ return r;
15418
+ case unstable_IdlePriority:
15419
+ return i$1;
15420
+ default:
15421
+ return r;
15422
+ }
15423
+ }
15424
+ default:
15425
+ return r;
15426
+ }
15427
+ }
15428
+ function scheduleMicrotask(callback) {
15429
+ if (typeof queueMicrotask === 'function') {
15430
+ queueMicrotask(callback);
15431
+ } else if (typeof Promise !== 'undefined') {
15432
+ Promise.resolve().then(callback).catch(error => {
15433
+ setTimeout(() => {
15434
+ throw error;
15435
+ });
15436
+ });
15437
+ } else {
15438
+ setTimeout(callback);
15439
+ }
15440
+ }
15287
15441
  const reconciler = /* @__PURE__ */createReconciler({
15288
15442
  isPrimaryRenderer: false,
15289
15443
  warnsIfNotActing: false,
@@ -15327,30 +15481,30 @@ const reconciler = /* @__PURE__ */createReconciler({
15327
15481
  return value !== ((_oldProps$args2 = oldProps.args) == null ? void 0 : _oldProps$args2[index]);
15328
15482
  })) reconstruct = true;
15329
15483
 
15330
- // Reconstruct when args or <primitive object={...} have changes
15484
+ // Reconstruct when args or <primitive object={...} have changes.
15485
+ // Instances are swapped at the end of the mutation phase (resetAfterCommit)
15331
15486
  if (reconstruct) {
15332
- reconstructed.push([instance, {
15333
- ...newProps
15334
- }, fiber]);
15487
+ reconstructed.push([instance, getInstanceProps(newProps), fiber]);
15335
15488
  } else {
15336
15489
  // Create a diff-set, flag if there are any changes
15337
15490
  const changedProps = diffProps(instance, newProps);
15338
- if (Object.keys(changedProps).length) {
15339
- Object.assign(instance.props, changedProps);
15340
- applyProps(instance.object, changedProps);
15341
- }
15342
- }
15343
15491
 
15344
- // Flush reconstructed siblings when we hit the last updated child in a sequence
15345
- const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
15346
- if (isTailSibling) swapInstances();
15492
+ // Replace the old prop snapshot after computing the diff
15493
+ //`attach` is preserved since it cannot be updated dynamically
15494
+ const attach = instance.props.attach;
15495
+ instance.props = getInstanceProps(newProps);
15496
+ if (attach !== undefined) instance.props.attach = attach;else delete instance.props.attach;
15497
+ if (Object.keys(changedProps).length) applyProps(instance.object, changedProps);
15498
+ }
15347
15499
  },
15348
15500
  finalizeInitialChildren: () => false,
15349
15501
  commitMount() {},
15350
15502
  getPublicInstance: instance => instance == null ? void 0 : instance.object,
15351
15503
  prepareForCommit: () => null,
15352
15504
  preparePortalMount: container => prepare(container.getState().scene, container, '', {}),
15353
- resetAfterCommit: () => {},
15505
+ // Reconstructed instances are swapped once all mutations are committed,
15506
+ // before layout effects run so refs point to the new objects
15507
+ resetAfterCommit: flushReconstructedInstances,
15354
15508
  shouldSetTextContent: () => false,
15355
15509
  clearContainer: () => false,
15356
15510
  hideInstance,
@@ -15358,6 +15512,9 @@ const reconciler = /* @__PURE__ */createReconciler({
15358
15512
  createTextInstance: handleTextInstance,
15359
15513
  hideTextInstance: handleTextInstance,
15360
15514
  unhideTextInstance: handleTextInstance,
15515
+ // Mirrors react-dom, which flushes discrete work in microtasks
15516
+ supportsMicrotasks: true,
15517
+ scheduleMicrotask,
15361
15518
  scheduleTimeout: typeof setTimeout === 'function' ? setTimeout : undefined,
15362
15519
  cancelTimeout: typeof clearTimeout === 'function' ? clearTimeout : undefined,
15363
15520
  noTimeout: -1,
@@ -15390,24 +15547,9 @@ const reconciler = /* @__PURE__ */createReconciler({
15390
15547
  resolveUpdatePriority() {
15391
15548
  var _window$event;
15392
15549
  if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;
15393
- switch (typeof window !== 'undefined' && ((_window$event = window.event) == null ? void 0 : _window$event.type)) {
15394
- case 'click':
15395
- case 'contextmenu':
15396
- case 'dblclick':
15397
- case 'pointercancel':
15398
- case 'pointerdown':
15399
- case 'pointerup':
15400
- return e;
15401
- case 'pointermove':
15402
- case 'pointerout':
15403
- case 'pointerover':
15404
- case 'pointerenter':
15405
- case 'pointerleave':
15406
- case 'wheel':
15407
- return o;
15408
- default:
15409
- return r;
15410
- }
15550
+ const eventType = typeof window !== 'undefined' ? (_window$event = window.event) == null ? void 0 : _window$event.type : undefined;
15551
+ if (eventType === undefined) return r;
15552
+ return getEventPriority(eventType);
15411
15553
  },
15412
15554
  resetFormInstance() {},
15413
15555
  // @ts-ignore DefinitelyTyped is not up to date
@@ -380,10 +380,10 @@ function diffProps(instance, newProps) {
380
380
  if (root.constructor && root.constructor.length === 0) {
381
381
  // create a blank slate of the instance and copy the particular parameter.
382
382
  const ctor = getMemoizedPrototype(root);
383
- if (!is.und(ctor)) changedProps[key] = ctor[key];
383
+ if (!is.und(ctor)) changedProps[prop] = ctor[key];
384
384
  } else {
385
385
  // instance does not have constructor, just set it to 0
386
- changedProps[key] = 0;
386
+ changedProps[prop] = 0;
387
387
  }
388
388
  }
389
389
  return changedProps;
@@ -542,6 +542,37 @@ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
542
542
  }
543
543
  }
544
544
  }
545
+
546
+ /** This function transfers all interactivity state from one object instance to another. Used when swapping instances due to reconstruction. */
547
+ function swapInteractivity(store, object, newObject) {
548
+ const {
549
+ internal
550
+ } = store.getState();
551
+ for (let i = 0; i < internal.interaction.length; i++) {
552
+ if (internal.interaction[i] === object) internal.interaction[i] = newObject;
553
+ }
554
+ for (let i = 0; i < internal.initialHits.length; i++) {
555
+ if (internal.initialHits[i] === object) internal.initialHits[i] = newObject;
556
+ }
557
+ internal.hovered.forEach((value, key) => {
558
+ if (value.eventObject === object || value.object === object) {
559
+ internal.hovered.delete(key);
560
+ const next = {
561
+ ...value,
562
+ eventObject: value.eventObject === object ? newObject : value.eventObject,
563
+ object: value.object === object ? newObject : value.object
564
+ };
565
+ internal.hovered.set(makeId(next), next);
566
+ }
567
+ });
568
+ internal.capturedMap.forEach(captures => {
569
+ const captureData = captures.get(object);
570
+ if (captureData) {
571
+ captures.delete(object);
572
+ captures.set(newObject, captureData);
573
+ }
574
+ });
575
+ }
545
576
  function removeInteractivity(store, object) {
546
577
  const {
547
578
  internal
@@ -1305,11 +1336,12 @@ useLoader.clear = function (loader, input) {
1305
1336
  */const t = 1,
1306
1337
  o = 8,
1307
1338
  r = 32,
1308
- e = 2;
1339
+ e = 2,
1340
+ i$1 = 268435456;
1309
1341
 
1310
1342
  var packageData = {
1311
1343
  name: "@react-three/fiber",
1312
- version: "9.6.0",
1344
+ version: "9.7.0",
1313
1345
  description: "A React renderer for Threejs",
1314
1346
  keywords: [
1315
1347
  "react",
@@ -6948,6 +6980,12 @@ function handleContainerEffects(parent, child, beforeChild) {
6948
6980
  function appendChild(parent, child) {
6949
6981
  if (!child) return;
6950
6982
 
6983
+ // Move an existing child instead of duplicating it
6984
+ if (child.parent === parent) {
6985
+ const childIndex = parent.children.indexOf(child);
6986
+ if (childIndex !== -1) parent.children.splice(childIndex, 1);
6987
+ }
6988
+
6951
6989
  // Link instances
6952
6990
  child.parent = parent;
6953
6991
  parent.children.push(child);
@@ -6958,6 +6996,12 @@ function appendChild(parent, child) {
6958
6996
  function insertBefore(parent, child, beforeChild) {
6959
6997
  if (!child || !beforeChild) return;
6960
6998
 
6999
+ // Move an existing child instead of duplicating it.
7000
+ if (child.parent === parent) {
7001
+ const childIndex = parent.children.indexOf(child);
7002
+ if (childIndex !== -1) parent.children.splice(childIndex, 1);
7003
+ }
7004
+
6961
7005
  // Link instances
6962
7006
  child.parent = parent;
6963
7007
  const childIndex = parent.children.indexOf(beforeChild);
@@ -7038,7 +7082,15 @@ function setFiberRef(fiber, publicInstance) {
7038
7082
  }
7039
7083
  }
7040
7084
  const reconstructed = [];
7041
- function swapInstances() {
7085
+ function flushReconstructedInstances() {
7086
+ if (reconstructed.length === 0) return;
7087
+ try {
7088
+ swapReconstructedInstances();
7089
+ } finally {
7090
+ reconstructed.length = 0;
7091
+ }
7092
+ }
7093
+ function swapReconstructedInstances() {
7042
7094
  // Detach instance
7043
7095
  for (const [instance] of reconstructed) {
7044
7096
  const parent = instance.parent;
@@ -7078,11 +7130,11 @@ function swapInstances() {
7078
7130
  const target = catalogue[toPascalCase(instance.type)];
7079
7131
 
7080
7132
  // Create object
7133
+ const prevObject = instance.object;
7081
7134
  instance.object = (_instance$props$objec = instance.props.object) != null ? _instance$props$objec : new target(...((_instance$props$args = instance.props.args) != null ? _instance$props$args : []));
7082
7135
  instance.object.__r3f = instance;
7083
7136
  setFiberRef(fiber, instance.object);
7084
-
7085
- // Set initial props
7137
+ swapInteractivity(findInitialRoot(instance), prevObject, instance.object);
7086
7138
  applyProps(instance.object, instance.props);
7087
7139
  if (instance.props.attach) {
7088
7140
  attach(parent, instance);
@@ -7101,7 +7153,6 @@ function swapInstances() {
7101
7153
  invalidateInstance(instance);
7102
7154
  }
7103
7155
  }
7104
- reconstructed.length = 0;
7105
7156
  }
7106
7157
 
7107
7158
  // Don't handle text instances, make it no-op
@@ -7109,9 +7160,112 @@ const handleTextInstance = () => {};
7109
7160
  const NO_CONTEXT = {};
7110
7161
  let currentUpdatePriority = NoEventPriority;
7111
7162
 
7112
- // https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberFlags.js
7113
- const NoFlags = 0;
7114
- const Update = 4;
7163
+ // Mirrors react-dom's getEventPriority for parity with events outside of React
7164
+ // https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/events/ReactDOMEventListener.js
7165
+ function getEventPriority(type) {
7166
+ switch (type) {
7167
+ case 'beforetoggle':
7168
+ case 'cancel':
7169
+ case 'click':
7170
+ case 'close':
7171
+ case 'contextmenu':
7172
+ case 'copy':
7173
+ case 'cut':
7174
+ case 'auxclick':
7175
+ case 'dblclick':
7176
+ case 'dragend':
7177
+ case 'dragstart':
7178
+ case 'drop':
7179
+ case 'focusin':
7180
+ case 'focusout':
7181
+ case 'input':
7182
+ case 'invalid':
7183
+ case 'keydown':
7184
+ case 'keypress':
7185
+ case 'keyup':
7186
+ case 'mousedown':
7187
+ case 'mouseup':
7188
+ case 'paste':
7189
+ case 'pause':
7190
+ case 'play':
7191
+ case 'pointercancel':
7192
+ case 'pointerdown':
7193
+ case 'pointerup':
7194
+ case 'ratechange':
7195
+ case 'reset':
7196
+ case 'resize':
7197
+ case 'seeked':
7198
+ case 'submit':
7199
+ case 'touchcancel':
7200
+ case 'touchend':
7201
+ case 'touchstart':
7202
+ case 'volumechange':
7203
+ case 'change':
7204
+ case 'selectionchange':
7205
+ case 'compositionstart':
7206
+ case 'compositionend':
7207
+ case 'compositionupdate':
7208
+ case 'beforeinput':
7209
+ case 'blur':
7210
+ case 'fullscreenchange':
7211
+ case 'focus':
7212
+ case 'hashchange':
7213
+ case 'popstate':
7214
+ case 'select':
7215
+ case 'selectstart':
7216
+ return e;
7217
+ case 'drag':
7218
+ case 'dragenter':
7219
+ case 'dragexit':
7220
+ case 'dragleave':
7221
+ case 'dragover':
7222
+ case 'mousemove':
7223
+ case 'mouseout':
7224
+ case 'mouseover':
7225
+ case 'pointermove':
7226
+ case 'pointerout':
7227
+ case 'pointerover':
7228
+ case 'scroll':
7229
+ case 'touchmove':
7230
+ case 'wheel':
7231
+ case 'mouseenter':
7232
+ case 'mouseleave':
7233
+ case 'pointerenter':
7234
+ case 'pointerleave':
7235
+ return o;
7236
+ case 'message':
7237
+ {
7238
+ switch (Tb.unstable_getCurrentPriorityLevel()) {
7239
+ case Tb.unstable_ImmediatePriority:
7240
+ return e;
7241
+ case Tb.unstable_UserBlockingPriority:
7242
+ return o;
7243
+ case Tb.unstable_NormalPriority:
7244
+ case Tb.unstable_LowPriority:
7245
+ return r;
7246
+ case Tb.unstable_IdlePriority:
7247
+ return i$1;
7248
+ default:
7249
+ return r;
7250
+ }
7251
+ }
7252
+ default:
7253
+ return r;
7254
+ }
7255
+ }
7256
+ function scheduleMicrotask(callback) {
7257
+ if (typeof queueMicrotask === 'function') {
7258
+ queueMicrotask(callback);
7259
+ } else if (typeof Promise !== 'undefined') {
7260
+ Promise.resolve().then(callback).catch(error => {
7261
+ setTimeout(() => {
7262
+ throw error;
7263
+ });
7264
+ });
7265
+ } else {
7266
+ setTimeout(callback);
7267
+ }
7268
+ }
7115
7269
  const reconciler = /* @__PURE__ */createReconciler({
7116
7270
  isPrimaryRenderer: false,
7117
7271
  warnsIfNotActing: false,
@@ -7155,30 +7309,30 @@ const reconciler = /* @__PURE__ */createReconciler({
7155
7309
  return value !== ((_oldProps$args2 = oldProps.args) == null ? void 0 : _oldProps$args2[index]);
7156
7310
  })) reconstruct = true;
7157
7311
 
7158
- // Reconstruct when args or <primitive object={...} have changes
7312
+ // Reconstruct when args or <primitive object={...} have changes.
7313
+ // Instances are swapped at the end of the mutation phase (resetAfterCommit)
7159
7314
  if (reconstruct) {
7160
- reconstructed.push([instance, {
7161
- ...newProps
7162
- }, fiber]);
7315
+ reconstructed.push([instance, getInstanceProps(newProps), fiber]);
7163
7316
  } else {
7164
7317
  // Create a diff-set, flag if there are any changes
7165
7318
  const changedProps = diffProps(instance, newProps);
7166
- if (Object.keys(changedProps).length) {
7167
- Object.assign(instance.props, changedProps);
7168
- applyProps(instance.object, changedProps);
7169
- }
7170
- }
7171
7319
 
7172
- // Flush reconstructed siblings when we hit the last updated child in a sequence
7173
- const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
7174
- if (isTailSibling) swapInstances();
7320
+ // Replace the old prop snapshot after computing the diff
7321
+ //`attach` is preserved since it cannot be updated dynamically
7322
+ const attach = instance.props.attach;
7323
+ instance.props = getInstanceProps(newProps);
7324
+ if (attach !== undefined) instance.props.attach = attach;else delete instance.props.attach;
7325
+ if (Object.keys(changedProps).length) applyProps(instance.object, changedProps);
7326
+ }
7175
7327
  },
7176
7328
  finalizeInitialChildren: () => false,
7177
7329
  commitMount() {},
7178
7330
  getPublicInstance: instance => instance == null ? void 0 : instance.object,
7179
7331
  prepareForCommit: () => null,
7180
7332
  preparePortalMount: container => prepare(container.getState().scene, container, '', {}),
7181
- resetAfterCommit: () => {},
7333
+ // Reconstructed instances are swapped once all mutations are committed,
7334
+ // before layout effects run so refs point to the new objects
7335
+ resetAfterCommit: flushReconstructedInstances,
7182
7336
  shouldSetTextContent: () => false,
7183
7337
  clearContainer: () => false,
7184
7338
  hideInstance,
@@ -7186,6 +7340,9 @@ const reconciler = /* @__PURE__ */createReconciler({
7186
7340
  createTextInstance: handleTextInstance,
7187
7341
  hideTextInstance: handleTextInstance,
7188
7342
  unhideTextInstance: handleTextInstance,
7343
+ // Mirrors react-dom, which flushes discrete work in microtasks
7344
+ supportsMicrotasks: true,
7345
+ scheduleMicrotask,
7189
7346
  scheduleTimeout: typeof setTimeout === 'function' ? setTimeout : undefined,
7190
7347
  cancelTimeout: typeof clearTimeout === 'function' ? clearTimeout : undefined,
7191
7348
  noTimeout: -1,
@@ -7218,24 +7375,9 @@ const reconciler = /* @__PURE__ */createReconciler({
7218
7375
  resolveUpdatePriority() {
7219
7376
  var _window$event;
7220
7377
  if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;
7221
- switch (typeof window !== 'undefined' && ((_window$event = window.event) == null ? void 0 : _window$event.type)) {
7222
- case 'click':
7223
- case 'contextmenu':
7224
- case 'dblclick':
7225
- case 'pointercancel':
7226
- case 'pointerdown':
7227
- case 'pointerup':
7228
- return e;
7229
- case 'pointermove':
7230
- case 'pointerout':
7231
- case 'pointerover':
7232
- case 'pointerenter':
7233
- case 'pointerleave':
7234
- case 'wheel':
7235
- return o;
7236
- default:
7237
- return r;
7238
- }
7378
+ const eventType = typeof window !== 'undefined' ? (_window$event = window.event) == null ? void 0 : _window$event.type : undefined;
7379
+ if (eventType === undefined) return r;
7380
+ return getEventPriority(eventType);
7239
7381
  },
7240
7382
  resetFormInstance() {},
7241
7383
  // @ts-ignore DefinitelyTyped is not up to date
@@ -380,10 +380,10 @@ function diffProps(instance, newProps) {
380
380
  if (root.constructor && root.constructor.length === 0) {
381
381
  // create a blank slate of the instance and copy the particular parameter.
382
382
  const ctor = getMemoizedPrototype(root);
383
- if (!is.und(ctor)) changedProps[key] = ctor[key];
383
+ if (!is.und(ctor)) changedProps[prop] = ctor[key];
384
384
  } else {
385
385
  // instance does not have constructor, just set it to 0
386
- changedProps[key] = 0;
386
+ changedProps[prop] = 0;
387
387
  }
388
388
  }
389
389
  return changedProps;
@@ -542,6 +542,37 @@ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
542
542
  }
543
543
  }
544
544
  }
545
+
546
+ /** This function transfers all interactivity state from one object instance to another. Used when swapping instances due to reconstruction. */
547
+ function swapInteractivity(store, object, newObject) {
548
+ const {
549
+ internal
550
+ } = store.getState();
551
+ for (let i = 0; i < internal.interaction.length; i++) {
552
+ if (internal.interaction[i] === object) internal.interaction[i] = newObject;
553
+ }
554
+ for (let i = 0; i < internal.initialHits.length; i++) {
555
+ if (internal.initialHits[i] === object) internal.initialHits[i] = newObject;
556
+ }
557
+ internal.hovered.forEach((value, key) => {
558
+ if (value.eventObject === object || value.object === object) {
559
+ internal.hovered.delete(key);
560
+ const next = {
561
+ ...value,
562
+ eventObject: value.eventObject === object ? newObject : value.eventObject,
563
+ object: value.object === object ? newObject : value.object
564
+ };
565
+ internal.hovered.set(makeId(next), next);
566
+ }
567
+ });
568
+ internal.capturedMap.forEach(captures => {
569
+ const captureData = captures.get(object);
570
+ if (captureData) {
571
+ captures.delete(object);
572
+ captures.set(newObject, captureData);
573
+ }
574
+ });
575
+ }
545
576
  function removeInteractivity(store, object) {
546
577
  const {
547
578
  internal
@@ -1305,11 +1336,12 @@ useLoader.clear = function (loader, input) {
1305
1336
  */const t = 1,
1306
1337
  o = 8,
1307
1338
  r = 32,
1308
- e = 2;
1339
+ e = 2,
1340
+ i$1 = 268435456;
1309
1341
 
1310
1342
  var packageData = {
1311
1343
  name: "@react-three/fiber",
1312
- version: "9.6.0",
1344
+ version: "9.7.0",
1313
1345
  description: "A React renderer for Threejs",
1314
1346
  keywords: [
1315
1347
  "react",
@@ -15145,6 +15177,12 @@ function handleContainerEffects(parent, child, beforeChild) {
15145
15177
  function appendChild(parent, child) {
15146
15178
  if (!child) return;
15147
15179
 
15180
+ // Move an existing child instead of duplicating it
15181
+ if (child.parent === parent) {
15182
+ const childIndex = parent.children.indexOf(child);
15183
+ if (childIndex !== -1) parent.children.splice(childIndex, 1);
15184
+ }
15185
+
15148
15186
  // Link instances
15149
15187
  child.parent = parent;
15150
15188
  parent.children.push(child);
@@ -15155,6 +15193,12 @@ function appendChild(parent, child) {
15155
15193
  function insertBefore(parent, child, beforeChild) {
15156
15194
  if (!child || !beforeChild) return;
15157
15195
 
15196
+ // Move an existing child instead of duplicating it.
15197
+ if (child.parent === parent) {
15198
+ const childIndex = parent.children.indexOf(child);
15199
+ if (childIndex !== -1) parent.children.splice(childIndex, 1);
15200
+ }
15201
+
15158
15202
  // Link instances
15159
15203
  child.parent = parent;
15160
15204
  const childIndex = parent.children.indexOf(beforeChild);
@@ -15235,7 +15279,15 @@ function setFiberRef(fiber, publicInstance) {
15235
15279
  }
15236
15280
  }
15237
15281
  const reconstructed = [];
15238
- function swapInstances() {
15282
+ function flushReconstructedInstances() {
15283
+ if (reconstructed.length === 0) return;
15284
+ try {
15285
+ swapReconstructedInstances();
15286
+ } finally {
15287
+ reconstructed.length = 0;
15288
+ }
15289
+ }
15290
+ function swapReconstructedInstances() {
15239
15291
  // Detach instance
15240
15292
  for (const [instance] of reconstructed) {
15241
15293
  const parent = instance.parent;
@@ -15275,11 +15327,11 @@ function swapInstances() {
15275
15327
  const target = catalogue[toPascalCase(instance.type)];
15276
15328
 
15277
15329
  // Create object
15330
+ const prevObject = instance.object;
15278
15331
  instance.object = (_instance$props$objec = instance.props.object) != null ? _instance$props$objec : new target(...((_instance$props$args = instance.props.args) != null ? _instance$props$args : []));
15279
15332
  instance.object.__r3f = instance;
15280
15333
  setFiberRef(fiber, instance.object);
15281
-
15282
- // Set initial props
15334
+ swapInteractivity(findInitialRoot(instance), prevObject, instance.object);
15283
15335
  applyProps(instance.object, instance.props);
15284
15336
  if (instance.props.attach) {
15285
15337
  attach(parent, instance);
@@ -15298,7 +15350,6 @@ function swapInstances() {
15298
15350
  invalidateInstance(instance);
15299
15351
  }
15300
15352
  }
15301
- reconstructed.length = 0;
15302
15353
  }
15303
15354
 
15304
15355
  // Don't handle text instances, make it no-op
@@ -15306,9 +15357,112 @@ const handleTextInstance = () => {};
15306
15357
  const NO_CONTEXT = {};
15307
15358
  let currentUpdatePriority = NoEventPriority;
15308
15359
 
15309
- // https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberFlags.js
15310
- const NoFlags = 0;
15311
- const Update = 4;
15360
+ // Mirrors react-dom's getEventPriority for parity with events outside of React
15361
+ // https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/events/ReactDOMEventListener.js
15362
+ function getEventPriority(type) {
15363
+ switch (type) {
15364
+ case 'beforetoggle':
15365
+ case 'cancel':
15366
+ case 'click':
15367
+ case 'close':
15368
+ case 'contextmenu':
15369
+ case 'copy':
15370
+ case 'cut':
15371
+ case 'auxclick':
15372
+ case 'dblclick':
15373
+ case 'dragend':
15374
+ case 'dragstart':
15375
+ case 'drop':
15376
+ case 'focusin':
15377
+ case 'focusout':
15378
+ case 'input':
15379
+ case 'invalid':
15380
+ case 'keydown':
15381
+ case 'keypress':
15382
+ case 'keyup':
15383
+ case 'mousedown':
15384
+ case 'mouseup':
15385
+ case 'paste':
15386
+ case 'pause':
15387
+ case 'play':
15388
+ case 'pointercancel':
15389
+ case 'pointerdown':
15390
+ case 'pointerup':
15391
+ case 'ratechange':
15392
+ case 'reset':
15393
+ case 'resize':
15394
+ case 'seeked':
15395
+ case 'submit':
15396
+ case 'touchcancel':
15397
+ case 'touchend':
15398
+ case 'touchstart':
15399
+ case 'volumechange':
15400
+ case 'change':
15401
+ case 'selectionchange':
15402
+ case 'compositionstart':
15403
+ case 'compositionend':
15404
+ case 'compositionupdate':
15405
+ case 'beforeinput':
15406
+ case 'blur':
15407
+ case 'fullscreenchange':
15408
+ case 'focus':
15409
+ case 'hashchange':
15410
+ case 'popstate':
15411
+ case 'select':
15412
+ case 'selectstart':
15413
+ return e;
15414
+ case 'drag':
15415
+ case 'dragenter':
15416
+ case 'dragexit':
15417
+ case 'dragleave':
15418
+ case 'dragover':
15419
+ case 'mousemove':
15420
+ case 'mouseout':
15421
+ case 'mouseover':
15422
+ case 'pointermove':
15423
+ case 'pointerout':
15424
+ case 'pointerover':
15425
+ case 'scroll':
15426
+ case 'touchmove':
15427
+ case 'wheel':
15428
+ case 'mouseenter':
15429
+ case 'mouseleave':
15430
+ case 'pointerenter':
15431
+ case 'pointerleave':
15432
+ return o;
15433
+ case 'message':
15434
+ {
15435
+ switch (Tb.unstable_getCurrentPriorityLevel()) {
15436
+ case Tb.unstable_ImmediatePriority:
15437
+ return e;
15438
+ case Tb.unstable_UserBlockingPriority:
15439
+ return o;
15440
+ case Tb.unstable_NormalPriority:
15441
+ case Tb.unstable_LowPriority:
15442
+ return r;
15443
+ case Tb.unstable_IdlePriority:
15444
+ return i$1;
15445
+ default:
15446
+ return r;
15447
+ }
15448
+ }
15449
+ default:
15450
+ return r;
15451
+ }
15452
+ }
15453
+ function scheduleMicrotask(callback) {
15454
+ if (typeof queueMicrotask === 'function') {
15455
+ queueMicrotask(callback);
15456
+ } else if (typeof Promise !== 'undefined') {
15457
+ Promise.resolve().then(callback).catch(error => {
15458
+ setTimeout(() => {
15459
+ throw error;
15460
+ });
15461
+ });
15462
+ } else {
15463
+ setTimeout(callback);
15464
+ }
15465
+ }
15312
15466
  const reconciler = /* @__PURE__ */createReconciler({
15313
15467
  isPrimaryRenderer: false,
15314
15468
  warnsIfNotActing: false,
@@ -15352,30 +15506,30 @@ const reconciler = /* @__PURE__ */createReconciler({
15352
15506
  return value !== ((_oldProps$args2 = oldProps.args) == null ? void 0 : _oldProps$args2[index]);
15353
15507
  })) reconstruct = true;
15354
15508
 
15355
- // Reconstruct when args or <primitive object={...} have changes
15509
+ // Reconstruct when args or <primitive object={...} have changes.
15510
+ // Instances are swapped at the end of the mutation phase (resetAfterCommit)
15356
15511
  if (reconstruct) {
15357
- reconstructed.push([instance, {
15358
- ...newProps
15359
- }, fiber]);
15512
+ reconstructed.push([instance, getInstanceProps(newProps), fiber]);
15360
15513
  } else {
15361
15514
  // Create a diff-set, flag if there are any changes
15362
15515
  const changedProps = diffProps(instance, newProps);
15363
- if (Object.keys(changedProps).length) {
15364
- Object.assign(instance.props, changedProps);
15365
- applyProps(instance.object, changedProps);
15366
- }
15367
- }
15368
15516
 
15369
- // Flush reconstructed siblings when we hit the last updated child in a sequence
15370
- const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
15371
- if (isTailSibling) swapInstances();
15517
+ // Replace the old prop snapshot after computing the diff
15518
+ //`attach` is preserved since it cannot be updated dynamically
15519
+ const attach = instance.props.attach;
15520
+ instance.props = getInstanceProps(newProps);
15521
+ if (attach !== undefined) instance.props.attach = attach;else delete instance.props.attach;
15522
+ if (Object.keys(changedProps).length) applyProps(instance.object, changedProps);
15523
+ }
15372
15524
  },
15373
15525
  finalizeInitialChildren: () => false,
15374
15526
  commitMount() {},
15375
15527
  getPublicInstance: instance => instance == null ? void 0 : instance.object,
15376
15528
  prepareForCommit: () => null,
15377
15529
  preparePortalMount: container => prepare(container.getState().scene, container, '', {}),
15378
- resetAfterCommit: () => {},
15530
+ // Reconstructed instances are swapped once all mutations are committed,
15531
+ // before layout effects run so refs point to the new objects
15532
+ resetAfterCommit: flushReconstructedInstances,
15379
15533
  shouldSetTextContent: () => false,
15380
15534
  clearContainer: () => false,
15381
15535
  hideInstance,
@@ -15383,6 +15537,9 @@ const reconciler = /* @__PURE__ */createReconciler({
15383
15537
  createTextInstance: handleTextInstance,
15384
15538
  hideTextInstance: handleTextInstance,
15385
15539
  unhideTextInstance: handleTextInstance,
15540
+ // Mirrors react-dom, which flushes discrete work in microtasks
15541
+ supportsMicrotasks: true,
15542
+ scheduleMicrotask,
15386
15543
  scheduleTimeout: typeof setTimeout === 'function' ? setTimeout : undefined,
15387
15544
  cancelTimeout: typeof clearTimeout === 'function' ? clearTimeout : undefined,
15388
15545
  noTimeout: -1,
@@ -15415,24 +15572,9 @@ const reconciler = /* @__PURE__ */createReconciler({
15415
15572
  resolveUpdatePriority() {
15416
15573
  var _window$event;
15417
15574
  if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;
15418
- switch (typeof window !== 'undefined' && ((_window$event = window.event) == null ? void 0 : _window$event.type)) {
15419
- case 'click':
15420
- case 'contextmenu':
15421
- case 'dblclick':
15422
- case 'pointercancel':
15423
- case 'pointerdown':
15424
- case 'pointerup':
15425
- return e;
15426
- case 'pointermove':
15427
- case 'pointerout':
15428
- case 'pointerover':
15429
- case 'pointerenter':
15430
- case 'pointerleave':
15431
- case 'wheel':
15432
- return o;
15433
- default:
15434
- return r;
15435
- }
15575
+ const eventType = typeof window !== 'undefined' ? (_window$event = window.event) == null ? void 0 : _window$event.type : undefined;
15576
+ if (eventType === undefined) return r;
15577
+ return getEventPriority(eventType);
15436
15578
  },
15437
15579
  resetFormInstance() {},
15438
15580
  // @ts-ignore DefinitelyTyped is not up to date
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var events = require('./events-508aad4b.cjs.dev.js');
5
+ var events = require('./events-b1bdeb1a.cjs.dev.js');
6
6
  var React = require('react');
7
7
  var THREE = require('three');
8
8
  var useMeasure = require('react-use-measure');
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var events = require('./events-11ca7a92.cjs.prod.js');
5
+ var events = require('./events-4c71f21f.cjs.prod.js');
6
6
  var React = require('react');
7
7
  var THREE = require('three');
8
8
  var useMeasure = require('react-use-measure');
@@ -1,5 +1,5 @@
1
- import { e as extend, u as useBridge, a as useMutableCallback, b as useIsomorphicLayoutEffect, c as createRoot, i as isRef, E as ErrorBoundary, B as Block, d as unmountComponentAtNode, f as createPointerEvents } from './events-760a1017.esm.js';
2
- export { t as ReactThreeFiber, _ as _roots, x as act, k as addAfterEffect, j as addEffect, l as addTail, n as advance, s as applyProps, y as buildGraph, q as context, g as createEvents, o as createPortal, c as createRoot, w as dispose, f as events, e as extend, h as flushGlobalEffects, p as flushSync, v as getRootState, m as invalidate, r as reconciler, d as unmountComponentAtNode, D as useFrame, F as useGraph, z as useInstanceHandle, G as useLoader, A as useStore, C as useThree } from './events-760a1017.esm.js';
1
+ import { e as extend, u as useBridge, a as useMutableCallback, b as useIsomorphicLayoutEffect, c as createRoot, i as isRef, E as ErrorBoundary, B as Block, d as unmountComponentAtNode, f as createPointerEvents } from './events-156d8d12.esm.js';
2
+ export { t as ReactThreeFiber, _ as _roots, x as act, k as addAfterEffect, j as addEffect, l as addTail, n as advance, s as applyProps, y as buildGraph, q as context, g as createEvents, o as createPortal, c as createRoot, w as dispose, f as events, e as extend, h as flushGlobalEffects, p as flushSync, v as getRootState, m as invalidate, r as reconciler, d as unmountComponentAtNode, D as useFrame, F as useGraph, z as useInstanceHandle, G as useLoader, A as useStore, C as useThree } from './events-156d8d12.esm.js';
3
3
  import * as React from 'react';
4
4
  import * as THREE from 'three';
5
5
  import useMeasure from 'react-use-measure';
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var events = require('../../dist/events-508aad4b.cjs.dev.js');
5
+ var events = require('../../dist/events-b1bdeb1a.cjs.dev.js');
6
6
  var React = require('react');
7
7
  var THREE = require('three');
8
8
  var reactNative = require('react-native');
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var events = require('../../dist/events-11ca7a92.cjs.prod.js');
5
+ var events = require('../../dist/events-4c71f21f.cjs.prod.js');
6
6
  var React = require('react');
7
7
  var THREE = require('three');
8
8
  var reactNative = require('react-native');
@@ -1,5 +1,5 @@
1
- import { e as extend, u as useBridge, a as useMutableCallback, c as createRoot, b as useIsomorphicLayoutEffect, E as ErrorBoundary, B as Block, d as unmountComponentAtNode, f as createPointerEvents, g as createEvents } from '../../dist/events-760a1017.esm.js';
2
- export { t as ReactThreeFiber, _ as _roots, x as act, k as addAfterEffect, j as addEffect, l as addTail, n as advance, s as applyProps, y as buildGraph, q as context, g as createEvents, o as createPortal, c as createRoot, w as dispose, e as extend, h as flushGlobalEffects, p as flushSync, v as getRootState, m as invalidate, r as reconciler, d as unmountComponentAtNode, D as useFrame, F as useGraph, z as useInstanceHandle, G as useLoader, A as useStore, C as useThree } from '../../dist/events-760a1017.esm.js';
1
+ import { e as extend, u as useBridge, a as useMutableCallback, c as createRoot, b as useIsomorphicLayoutEffect, E as ErrorBoundary, B as Block, d as unmountComponentAtNode, f as createPointerEvents, g as createEvents } from '../../dist/events-156d8d12.esm.js';
2
+ export { t as ReactThreeFiber, _ as _roots, x as act, k as addAfterEffect, j as addEffect, l as addTail, n as advance, s as applyProps, y as buildGraph, q as context, g as createEvents, o as createPortal, c as createRoot, w as dispose, e as extend, h as flushGlobalEffects, p as flushSync, v as getRootState, m as invalidate, r as reconciler, d as unmountComponentAtNode, D as useFrame, F as useGraph, z as useInstanceHandle, G as useLoader, A as useStore, C as useThree } from '../../dist/events-156d8d12.esm.js';
3
3
  import * as React from 'react';
4
4
  import * as THREE from 'three';
5
5
  import { PanResponder, PixelRatio, StyleSheet, View, Platform, Image, NativeModules } from 'react-native';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/fiber",
3
- "version": "9.6.0",
3
+ "version": "9.7.0",
4
4
  "description": "A React renderer for Threejs",
5
5
  "keywords": [
6
6
  "react",