@react-three/fiber 10.0.0-canary.164c7be → 10.0.0-canary.1be335a
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/dist/index.cjs +344 -145
- package/dist/index.d.cts +49 -25
- package/dist/index.d.mts +49 -25
- package/dist/index.d.ts +49 -25
- package/dist/index.mjs +347 -148
- package/dist/legacy.cjs +299 -100
- package/dist/legacy.d.cts +49 -24
- package/dist/legacy.d.mts +49 -24
- package/dist/legacy.d.ts +49 -24
- package/dist/legacy.mjs +301 -102
- package/dist/webgpu/index.cjs +631 -673
- package/dist/webgpu/index.d.cts +83 -29
- package/dist/webgpu/index.d.mts +83 -29
- package/dist/webgpu/index.d.ts +83 -29
- package/dist/webgpu/index.mjs +634 -676
- package/package.json +3 -3
- package/readme.md +2 -3
package/dist/legacy.cjs
CHANGED
|
@@ -62,9 +62,12 @@ const WebGPURenderer = class WebGPURenderer2 {
|
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
const RenderTarget = null;
|
|
65
|
+
const CubeRenderTarget = null;
|
|
65
66
|
|
|
66
67
|
const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
67
68
|
__proto__: null,
|
|
69
|
+
CubeRenderTarget: CubeRenderTarget,
|
|
70
|
+
CubeRenderTargetCompat: three.WebGLCubeRenderTarget,
|
|
68
71
|
Inspector: Inspector,
|
|
69
72
|
R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
|
|
70
73
|
R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
|
|
@@ -342,15 +345,16 @@ function EnvironmentPortal({
|
|
|
342
345
|
preset = void 0,
|
|
343
346
|
extensions
|
|
344
347
|
}) {
|
|
345
|
-
const
|
|
348
|
+
const renderer = fiber.useThree((state) => state.renderer);
|
|
349
|
+
const isLegacy = fiber.useThree((state) => state.isLegacy);
|
|
346
350
|
const defaultScene = fiber.useThree((state) => state.scene);
|
|
347
351
|
const camera = React__namespace.useRef(null);
|
|
348
352
|
const [virtualScene] = React__namespace.useState(() => new three.Scene());
|
|
349
353
|
const fbo = React__namespace.useMemo(() => {
|
|
350
|
-
const fbo2 = new three.WebGLCubeRenderTarget(resolution);
|
|
354
|
+
const fbo2 = isLegacy ? new three.WebGLCubeRenderTarget(resolution) : new CubeRenderTarget(resolution);
|
|
351
355
|
fbo2.texture.type = three.HalfFloatType;
|
|
352
356
|
return fbo2;
|
|
353
|
-
}, [resolution]);
|
|
357
|
+
}, [resolution, isLegacy]);
|
|
354
358
|
React__namespace.useEffect(() => {
|
|
355
359
|
return () => {
|
|
356
360
|
fbo.dispose();
|
|
@@ -358,10 +362,10 @@ function EnvironmentPortal({
|
|
|
358
362
|
}, [fbo]);
|
|
359
363
|
React__namespace.useLayoutEffect(() => {
|
|
360
364
|
if (frames === 1) {
|
|
361
|
-
const autoClear =
|
|
362
|
-
|
|
363
|
-
camera.current.update(
|
|
364
|
-
|
|
365
|
+
const autoClear = renderer.autoClear;
|
|
366
|
+
renderer.autoClear = true;
|
|
367
|
+
camera.current.update(renderer, virtualScene);
|
|
368
|
+
renderer.autoClear = autoClear;
|
|
365
369
|
}
|
|
366
370
|
return setEnvProps(background, scene, defaultScene, fbo.texture, {
|
|
367
371
|
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
@@ -378,7 +382,7 @@ function EnvironmentPortal({
|
|
|
378
382
|
defaultScene,
|
|
379
383
|
background,
|
|
380
384
|
frames,
|
|
381
|
-
|
|
385
|
+
renderer,
|
|
382
386
|
blur,
|
|
383
387
|
backgroundBlurriness,
|
|
384
388
|
backgroundIntensity,
|
|
@@ -389,10 +393,10 @@ function EnvironmentPortal({
|
|
|
389
393
|
let count = 1;
|
|
390
394
|
fiber.useFrame(() => {
|
|
391
395
|
if (frames === Infinity || count < frames) {
|
|
392
|
-
const autoClear =
|
|
393
|
-
|
|
394
|
-
camera.current.update(
|
|
395
|
-
|
|
396
|
+
const autoClear = renderer.autoClear;
|
|
397
|
+
renderer.autoClear = true;
|
|
398
|
+
camera.current.update(renderer, virtualScene);
|
|
399
|
+
renderer.autoClear = autoClear;
|
|
396
400
|
count++;
|
|
397
401
|
}
|
|
398
402
|
});
|
|
@@ -635,8 +639,7 @@ function prepare(target, root, type, props) {
|
|
|
635
639
|
object,
|
|
636
640
|
eventCount: 0,
|
|
637
641
|
handlers: {},
|
|
638
|
-
isHidden: false
|
|
639
|
-
deferredRefs: []
|
|
642
|
+
isHidden: false
|
|
640
643
|
};
|
|
641
644
|
if (object) object.__r3f = instance;
|
|
642
645
|
}
|
|
@@ -793,6 +796,17 @@ function unregisterVisibility(store, object) {
|
|
|
793
796
|
internal.visibilityRegistry.delete(object.uuid);
|
|
794
797
|
internal.occlusionCache.delete(object);
|
|
795
798
|
}
|
|
799
|
+
function updateVisibilityHandlers(store, object, handlers) {
|
|
800
|
+
const { internal } = store.getState();
|
|
801
|
+
const entry = internal.visibilityRegistry.get(object.uuid);
|
|
802
|
+
if (!entry) return false;
|
|
803
|
+
entry.handlers = handlers;
|
|
804
|
+
if ((handlers.onOccluded || handlers.onVisible) && !internal.occlusionEnabled) {
|
|
805
|
+
object.occlusionTest = true;
|
|
806
|
+
enableOcclusion(store);
|
|
807
|
+
}
|
|
808
|
+
return true;
|
|
809
|
+
}
|
|
796
810
|
function checkVisibility(state) {
|
|
797
811
|
const { internal, camera } = state;
|
|
798
812
|
const registry = internal.visibilityRegistry;
|
|
@@ -953,9 +967,9 @@ function diffProps(instance, newProps) {
|
|
|
953
967
|
const { root, key } = resolve(instance.object, prop);
|
|
954
968
|
if (root.constructor && root.constructor.length === 0) {
|
|
955
969
|
const ctor = getMemoizedPrototype(root);
|
|
956
|
-
if (!is.und(ctor)) changedProps[
|
|
970
|
+
if (!is.und(ctor)) changedProps[prop] = ctor[key];
|
|
957
971
|
} else {
|
|
958
|
-
changedProps[
|
|
972
|
+
changedProps[prop] = 0;
|
|
959
973
|
}
|
|
960
974
|
}
|
|
961
975
|
return changedProps;
|
|
@@ -980,10 +994,7 @@ function applyProps(object, props) {
|
|
|
980
994
|
continue;
|
|
981
995
|
}
|
|
982
996
|
if (value === void 0) continue;
|
|
983
|
-
if (isFromRef(value))
|
|
984
|
-
instance?.deferredRefs?.push({ prop, ref: value[FROM_REF] });
|
|
985
|
-
continue;
|
|
986
|
-
}
|
|
997
|
+
if (isFromRef(value)) continue;
|
|
987
998
|
if (isOnce(value)) {
|
|
988
999
|
if (instance?.appliedOnce?.has(prop)) continue;
|
|
989
1000
|
if (instance) {
|
|
@@ -1019,6 +1030,19 @@ function applyProps(object, props) {
|
|
|
1019
1030
|
} else if (isVectorLike(target) && is.num(value)) {
|
|
1020
1031
|
if ("setScalar" in target && typeof target.setScalar === "function") target.setScalar(value);
|
|
1021
1032
|
else target.set(value);
|
|
1033
|
+
} else if (root instanceof three.ShaderMaterial && key === "uniforms" && is.obj(value)) {
|
|
1034
|
+
if (!is.obj(root.uniforms)) root.uniforms = {};
|
|
1035
|
+
const uniforms = root.uniforms;
|
|
1036
|
+
const nextUniforms = value;
|
|
1037
|
+
for (const name in nextUniforms) {
|
|
1038
|
+
const uniform = nextUniforms[name];
|
|
1039
|
+
const targetUniform = uniforms[name];
|
|
1040
|
+
if (targetUniform) Object.assign(targetUniform, uniform);
|
|
1041
|
+
else {
|
|
1042
|
+
const nextUniform = uniform instanceof three.Uniform ? uniform.clone() : new three.Uniform(uniform.value);
|
|
1043
|
+
uniforms[name] = nextUniform;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1022
1046
|
} else {
|
|
1023
1047
|
root[key] = value;
|
|
1024
1048
|
if (key.endsWith("Node") && root.isMaterial) {
|
|
@@ -1037,6 +1061,9 @@ function applyProps(object, props) {
|
|
|
1037
1061
|
if (instance.eventCount && object2.raycast !== null) {
|
|
1038
1062
|
rootState.internal.interaction.push(object2);
|
|
1039
1063
|
}
|
|
1064
|
+
}
|
|
1065
|
+
if (instance?.parent && rootState?.internal && instance.object?.isObject3D) {
|
|
1066
|
+
const object2 = instance.object;
|
|
1040
1067
|
const root = findInitialRoot(instance);
|
|
1041
1068
|
const visibilityHandlers = {
|
|
1042
1069
|
onFramed: instance.handlers.onFramed,
|
|
@@ -1044,7 +1071,9 @@ function applyProps(object, props) {
|
|
|
1044
1071
|
onVisible: instance.handlers.onVisible
|
|
1045
1072
|
};
|
|
1046
1073
|
if (hasVisibilityHandlers(visibilityHandlers)) {
|
|
1047
|
-
|
|
1074
|
+
if (!updateVisibilityHandlers(root, object2, visibilityHandlers)) {
|
|
1075
|
+
registerVisibility(root, object2, visibilityHandlers);
|
|
1076
|
+
}
|
|
1048
1077
|
} else {
|
|
1049
1078
|
unregisterVisibility(root, object2);
|
|
1050
1079
|
}
|
|
@@ -1572,6 +1601,7 @@ function createPointerEvents(store) {
|
|
|
1572
1601
|
set((state) => ({ events: { ...state.events, connected: void 0 } }));
|
|
1573
1602
|
}
|
|
1574
1603
|
},
|
|
1604
|
+
// PREVIEW (A8): the XR pointer registration API may change before stable.
|
|
1575
1605
|
registerPointer: (config) => {
|
|
1576
1606
|
const pointerId = nextXRPointerId++;
|
|
1577
1607
|
xrPointers.set(pointerId, config);
|
|
@@ -1658,6 +1688,13 @@ function notifyAlpha({ message, link }) {
|
|
|
1658
1688
|
}
|
|
1659
1689
|
}
|
|
1660
1690
|
|
|
1691
|
+
const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
|
|
1692
|
+
function isInternalRendererAccess(stack, callerDepth = 2) {
|
|
1693
|
+
if (!stack) return false;
|
|
1694
|
+
const caller = stack.split("\n")[callerDepth] ?? "";
|
|
1695
|
+
return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1661
1698
|
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
1662
1699
|
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React__namespace.createContext(null));
|
|
1663
1700
|
const createStore = (invalidate, advance) => {
|
|
@@ -1790,6 +1827,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1790
1827
|
}),
|
|
1791
1828
|
setFrameloop: (frameloop = "always") => {
|
|
1792
1829
|
set(() => ({ frameloop }));
|
|
1830
|
+
scheduler.getScheduler().frameloop = frameloop;
|
|
1793
1831
|
},
|
|
1794
1832
|
setError: (error) => set(() => ({ error })),
|
|
1795
1833
|
error: null,
|
|
@@ -1857,8 +1895,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1857
1895
|
const currentState = rootStore.getState();
|
|
1858
1896
|
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
1859
1897
|
const stack = new Error().stack || "";
|
|
1860
|
-
|
|
1861
|
-
if (!isInternalAccess) {
|
|
1898
|
+
if (!isInternalRendererAccess(stack)) {
|
|
1862
1899
|
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
1863
1900
|
notifyDepreciated({
|
|
1864
1901
|
heading: "Accessing state.gl in WebGPU mode",
|
|
@@ -1971,19 +2008,25 @@ function loadingFn(extensions, onProgress) {
|
|
|
1971
2008
|
);
|
|
1972
2009
|
};
|
|
1973
2010
|
}
|
|
1974
|
-
function useLoader(loader, input, extensions, onProgress) {
|
|
1975
|
-
const
|
|
2011
|
+
function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
2012
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
2013
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
1976
2014
|
const fn = loadingFn(extensions, onProgress);
|
|
1977
|
-
const results =
|
|
2015
|
+
const results = cacheKeys.map(
|
|
2016
|
+
(key, index) => suspendReact.suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
2017
|
+
);
|
|
1978
2018
|
return Array.isArray(input) ? results : results[0];
|
|
1979
2019
|
}
|
|
1980
|
-
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
1981
|
-
const
|
|
1982
|
-
|
|
2020
|
+
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
2021
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
2022
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
2023
|
+
cacheKeys.forEach(
|
|
2024
|
+
(key, index) => suspendReact.preload(() => loadingFn(extensions, onProgress)(loader, inputs[index]), [loader, key])
|
|
2025
|
+
);
|
|
1983
2026
|
};
|
|
1984
|
-
useLoader.clear = function(loader, input) {
|
|
1985
|
-
const
|
|
1986
|
-
|
|
2027
|
+
useLoader.clear = function(loader, input, cacheKey) {
|
|
2028
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
2029
|
+
cacheKeys.forEach((key) => suspendReact.clear([loader, key]));
|
|
1987
2030
|
};
|
|
1988
2031
|
useLoader.loader = getLoader;
|
|
1989
2032
|
|
|
@@ -2403,7 +2446,7 @@ function advance(timestamp) {
|
|
|
2403
2446
|
scheduler.getScheduler().step(timestamp);
|
|
2404
2447
|
}
|
|
2405
2448
|
|
|
2406
|
-
const version = "10.0.0-alpha.
|
|
2449
|
+
const version = "10.0.0-alpha.3";
|
|
2407
2450
|
const packageData = {
|
|
2408
2451
|
version: version};
|
|
2409
2452
|
|
|
@@ -13659,7 +13702,7 @@ function n0() {
|
|
|
13659
13702
|
var t0 = n0();
|
|
13660
13703
|
const r0 = Xb(t0);
|
|
13661
13704
|
|
|
13662
|
-
const t = 1, o = 8, r = 32, e = 2;
|
|
13705
|
+
const t = 1, o = 8, r = 32, e = 2, i$1 = 268435456;
|
|
13663
13706
|
|
|
13664
13707
|
function createReconciler(config) {
|
|
13665
13708
|
const reconciler2 = r0(config);
|
|
@@ -13824,7 +13867,15 @@ function setFiberRef(fiber, publicInstance) {
|
|
|
13824
13867
|
}
|
|
13825
13868
|
}
|
|
13826
13869
|
const reconstructed = [];
|
|
13827
|
-
function
|
|
13870
|
+
function flushReconstructedInstances() {
|
|
13871
|
+
if (reconstructed.length === 0) return;
|
|
13872
|
+
try {
|
|
13873
|
+
swapReconstructedInstances();
|
|
13874
|
+
} finally {
|
|
13875
|
+
reconstructed.length = 0;
|
|
13876
|
+
}
|
|
13877
|
+
}
|
|
13878
|
+
function swapReconstructedInstances() {
|
|
13828
13879
|
for (const [instance] of reconstructed) {
|
|
13829
13880
|
const parent = instance.parent;
|
|
13830
13881
|
if (parent) {
|
|
@@ -13842,6 +13893,7 @@ function swapInstances() {
|
|
|
13842
13893
|
}
|
|
13843
13894
|
}
|
|
13844
13895
|
if (instance.isHidden) unhideInstance(instance);
|
|
13896
|
+
if (isObject3D(instance.object)) removeInteractivity(findInitialRoot(instance), instance.object);
|
|
13845
13897
|
if (instance.object.__r3f) delete instance.object.__r3f;
|
|
13846
13898
|
if (instance.type !== "primitive") disposeOnIdle(instance.object);
|
|
13847
13899
|
}
|
|
@@ -13854,6 +13906,8 @@ function swapInstances() {
|
|
|
13854
13906
|
instance.object.__r3f = instance;
|
|
13855
13907
|
setFiberRef(fiber, instance.object);
|
|
13856
13908
|
delete instance.appliedOnce;
|
|
13909
|
+
instance.eventCount = 0;
|
|
13910
|
+
instance.handlers = {};
|
|
13857
13911
|
applyProps(instance.object, instance.props);
|
|
13858
13912
|
if (instance.props.attach) {
|
|
13859
13913
|
attach(parent, instance);
|
|
@@ -13870,14 +13924,114 @@ function swapInstances() {
|
|
|
13870
13924
|
invalidateInstance(instance);
|
|
13871
13925
|
}
|
|
13872
13926
|
}
|
|
13873
|
-
reconstructed.length = 0;
|
|
13874
13927
|
}
|
|
13875
13928
|
const handleTextInstance = () => {
|
|
13876
13929
|
};
|
|
13877
13930
|
const NO_CONTEXT = {};
|
|
13878
13931
|
let currentUpdatePriority = NoEventPriority;
|
|
13879
|
-
|
|
13880
|
-
|
|
13932
|
+
function getEventPriority(type) {
|
|
13933
|
+
switch (type) {
|
|
13934
|
+
case "beforetoggle":
|
|
13935
|
+
case "cancel":
|
|
13936
|
+
case "click":
|
|
13937
|
+
case "close":
|
|
13938
|
+
case "contextmenu":
|
|
13939
|
+
case "copy":
|
|
13940
|
+
case "cut":
|
|
13941
|
+
case "auxclick":
|
|
13942
|
+
case "dblclick":
|
|
13943
|
+
case "dragend":
|
|
13944
|
+
case "dragstart":
|
|
13945
|
+
case "drop":
|
|
13946
|
+
case "focusin":
|
|
13947
|
+
case "focusout":
|
|
13948
|
+
case "input":
|
|
13949
|
+
case "invalid":
|
|
13950
|
+
case "keydown":
|
|
13951
|
+
case "keypress":
|
|
13952
|
+
case "keyup":
|
|
13953
|
+
case "mousedown":
|
|
13954
|
+
case "mouseup":
|
|
13955
|
+
case "paste":
|
|
13956
|
+
case "pause":
|
|
13957
|
+
case "play":
|
|
13958
|
+
case "pointercancel":
|
|
13959
|
+
case "pointerdown":
|
|
13960
|
+
case "pointerup":
|
|
13961
|
+
case "ratechange":
|
|
13962
|
+
case "reset":
|
|
13963
|
+
case "resize":
|
|
13964
|
+
case "seeked":
|
|
13965
|
+
case "submit":
|
|
13966
|
+
case "touchcancel":
|
|
13967
|
+
case "touchend":
|
|
13968
|
+
case "touchstart":
|
|
13969
|
+
case "volumechange":
|
|
13970
|
+
case "change":
|
|
13971
|
+
case "selectionchange":
|
|
13972
|
+
case "compositionstart":
|
|
13973
|
+
case "compositionend":
|
|
13974
|
+
case "compositionupdate":
|
|
13975
|
+
case "beforeinput":
|
|
13976
|
+
case "blur":
|
|
13977
|
+
case "fullscreenchange":
|
|
13978
|
+
case "focus":
|
|
13979
|
+
case "hashchange":
|
|
13980
|
+
case "popstate":
|
|
13981
|
+
case "select":
|
|
13982
|
+
case "selectstart":
|
|
13983
|
+
return e;
|
|
13984
|
+
case "drag":
|
|
13985
|
+
case "dragenter":
|
|
13986
|
+
case "dragexit":
|
|
13987
|
+
case "dragleave":
|
|
13988
|
+
case "dragover":
|
|
13989
|
+
case "mousemove":
|
|
13990
|
+
case "mouseout":
|
|
13991
|
+
case "mouseover":
|
|
13992
|
+
case "pointermove":
|
|
13993
|
+
case "pointerout":
|
|
13994
|
+
case "pointerover":
|
|
13995
|
+
case "scroll":
|
|
13996
|
+
case "touchmove":
|
|
13997
|
+
case "wheel":
|
|
13998
|
+
case "mouseenter":
|
|
13999
|
+
case "mouseleave":
|
|
14000
|
+
case "pointerenter":
|
|
14001
|
+
case "pointerleave":
|
|
14002
|
+
return o;
|
|
14003
|
+
case "message": {
|
|
14004
|
+
switch (Tb.unstable_getCurrentPriorityLevel()) {
|
|
14005
|
+
case Tb.unstable_ImmediatePriority:
|
|
14006
|
+
return e;
|
|
14007
|
+
case Tb.unstable_UserBlockingPriority:
|
|
14008
|
+
return o;
|
|
14009
|
+
case Tb.unstable_NormalPriority:
|
|
14010
|
+
case Tb.unstable_LowPriority:
|
|
14011
|
+
return r;
|
|
14012
|
+
case Tb.unstable_IdlePriority:
|
|
14013
|
+
return i$1;
|
|
14014
|
+
default:
|
|
14015
|
+
return r;
|
|
14016
|
+
}
|
|
14017
|
+
}
|
|
14018
|
+
default:
|
|
14019
|
+
return r;
|
|
14020
|
+
}
|
|
14021
|
+
}
|
|
14022
|
+
function scheduleMicrotask(callback) {
|
|
14023
|
+
if (typeof queueMicrotask === "function") {
|
|
14024
|
+
queueMicrotask(callback);
|
|
14025
|
+
} else if (typeof Promise !== "undefined") {
|
|
14026
|
+
Promise.resolve().then(callback).catch((error) => {
|
|
14027
|
+
setTimeout(() => {
|
|
14028
|
+
throw error;
|
|
14029
|
+
});
|
|
14030
|
+
});
|
|
14031
|
+
} else {
|
|
14032
|
+
setTimeout(callback);
|
|
14033
|
+
}
|
|
14034
|
+
}
|
|
13881
14035
|
const reconciler = /* @__PURE__ */ createReconciler({
|
|
13882
14036
|
isPrimaryRenderer: false,
|
|
13883
14037
|
warnsIfNotActing: false,
|
|
@@ -13916,16 +14070,15 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13916
14070
|
else if (newProps.args?.length !== oldProps.args?.length) reconstruct = true;
|
|
13917
14071
|
else if (newProps.args?.some((value, index) => value !== oldProps.args?.[index])) reconstruct = true;
|
|
13918
14072
|
if (reconstruct) {
|
|
13919
|
-
reconstructed.push([instance,
|
|
14073
|
+
reconstructed.push([instance, getInstanceProps(newProps), fiber]);
|
|
13920
14074
|
} else {
|
|
13921
14075
|
const changedProps = diffProps(instance, newProps);
|
|
13922
|
-
|
|
13923
|
-
|
|
13924
|
-
|
|
13925
|
-
|
|
14076
|
+
const attach2 = instance.props.attach;
|
|
14077
|
+
instance.props = getInstanceProps(newProps);
|
|
14078
|
+
if (attach2 !== void 0) instance.props.attach = attach2;
|
|
14079
|
+
else delete instance.props.attach;
|
|
14080
|
+
if (Object.keys(changedProps).length) applyProps(instance.object, changedProps);
|
|
13926
14081
|
}
|
|
13927
|
-
const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
|
|
13928
|
-
if (isTailSibling) swapInstances();
|
|
13929
14082
|
},
|
|
13930
14083
|
finalizeInitialChildren: (instance) => {
|
|
13931
14084
|
for (const prop in instance.props) {
|
|
@@ -13950,8 +14103,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13950
14103
|
const target = container.getState().internal.container ?? container.getState().scene;
|
|
13951
14104
|
return prepare(target, container, "", {});
|
|
13952
14105
|
},
|
|
13953
|
-
|
|
13954
|
-
|
|
14106
|
+
// Reconstructed instances are swapped once all mutations are committed,
|
|
14107
|
+
// before layout effects run so refs point to the new objects
|
|
14108
|
+
resetAfterCommit: flushReconstructedInstances,
|
|
13955
14109
|
shouldSetTextContent: () => false,
|
|
13956
14110
|
clearContainer: () => false,
|
|
13957
14111
|
hideInstance,
|
|
@@ -13959,6 +14113,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13959
14113
|
createTextInstance: handleTextInstance,
|
|
13960
14114
|
hideTextInstance: handleTextInstance,
|
|
13961
14115
|
unhideTextInstance: handleTextInstance,
|
|
14116
|
+
// Mirrors react-dom, which flushes discrete work in microtasks
|
|
14117
|
+
supportsMicrotasks: true,
|
|
14118
|
+
scheduleMicrotask,
|
|
13962
14119
|
scheduleTimeout: typeof setTimeout === "function" ? setTimeout : void 0,
|
|
13963
14120
|
cancelTimeout: typeof clearTimeout === "function" ? clearTimeout : void 0,
|
|
13964
14121
|
noTimeout: -1,
|
|
@@ -13999,28 +14156,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13999
14156
|
},
|
|
14000
14157
|
resolveUpdatePriority() {
|
|
14001
14158
|
if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;
|
|
14002
|
-
|
|
14003
|
-
|
|
14004
|
-
|
|
14005
|
-
case "dblclick":
|
|
14006
|
-
case "dragenter":
|
|
14007
|
-
case "dragleave":
|
|
14008
|
-
case "drop":
|
|
14009
|
-
case "pointercancel":
|
|
14010
|
-
case "pointerdown":
|
|
14011
|
-
case "pointerup":
|
|
14012
|
-
return e;
|
|
14013
|
-
case "dragover":
|
|
14014
|
-
case "pointermove":
|
|
14015
|
-
case "pointerout":
|
|
14016
|
-
case "pointerover":
|
|
14017
|
-
case "pointerenter":
|
|
14018
|
-
case "pointerleave":
|
|
14019
|
-
case "wheel":
|
|
14020
|
-
return o;
|
|
14021
|
-
default:
|
|
14022
|
-
return r;
|
|
14023
|
-
}
|
|
14159
|
+
const eventType = typeof window !== "undefined" ? window.event?.type : void 0;
|
|
14160
|
+
if (eventType === void 0) return r;
|
|
14161
|
+
return getEventPriority(eventType);
|
|
14024
14162
|
},
|
|
14025
14163
|
resetFormInstance() {
|
|
14026
14164
|
},
|
|
@@ -14069,11 +14207,15 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14069
14207
|
cloneMutableTextInstance(textInstance) {
|
|
14070
14208
|
return textInstance;
|
|
14071
14209
|
},
|
|
14210
|
+
// React 19.2 added these for root-level view transitions. They only run for hosts that opt into
|
|
14211
|
+
// view transitions by returning a container from cloneRootViewTransitionContainer; R3F renders
|
|
14212
|
+
// into a WebGL/WebGPU canvas, where cloning the root has no meaning, so we never opt in and
|
|
14213
|
+
// React never calls them. They stay as no-ops rather than throws: the host config is shared by
|
|
14214
|
+
// every root, and a throw here would turn a React-internal probe into a hard crash for users.
|
|
14215
|
+
// Guarded by a test asserting a full render + unmount never reaches them.
|
|
14072
14216
|
cloneRootViewTransitionContainer(_rootContainer) {
|
|
14073
|
-
throw new Error("Not implemented.");
|
|
14074
14217
|
},
|
|
14075
14218
|
removeRootViewTransitionClone(_rootContainer, _clone) {
|
|
14076
|
-
throw new Error("Not implemented.");
|
|
14077
14219
|
},
|
|
14078
14220
|
// https://github.com/facebook/react/pull/32465
|
|
14079
14221
|
createFragmentInstance: (_fiber) => null,
|
|
@@ -14158,6 +14300,7 @@ function createRoot(canvas) {
|
|
|
14158
14300
|
const lastConfiguredProps = {};
|
|
14159
14301
|
let configured = false;
|
|
14160
14302
|
let pending = null;
|
|
14303
|
+
let rendererSetup = null;
|
|
14161
14304
|
return {
|
|
14162
14305
|
async configure(props = {}) {
|
|
14163
14306
|
let resolve;
|
|
@@ -14188,7 +14331,7 @@ function createRoot(canvas) {
|
|
|
14188
14331
|
forceEven
|
|
14189
14332
|
} = props;
|
|
14190
14333
|
const textureColorSpace = is.obj(glConfig) && !is.fun(glConfig) && !isRenderer(glConfig) && glConfig.textureColorSpace || is.obj(rendererConfig) && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && rendererConfig.textureColorSpace || three.SRGBColorSpace;
|
|
14191
|
-
|
|
14334
|
+
let state = store.getState();
|
|
14192
14335
|
const defaultGLProps = {
|
|
14193
14336
|
canvas,
|
|
14194
14337
|
powerPreference: "high-performance",
|
|
@@ -14216,9 +14359,21 @@ function createRoot(canvas) {
|
|
|
14216
14359
|
);
|
|
14217
14360
|
}
|
|
14218
14361
|
if (!state.internal.actualRenderer) {
|
|
14219
|
-
|
|
14220
|
-
|
|
14221
|
-
|
|
14362
|
+
if (!rendererSetup) {
|
|
14363
|
+
rendererSetup = (async () => {
|
|
14364
|
+
{
|
|
14365
|
+
renderer = await resolveRenderer(glConfig, defaultGLProps, three.WebGLRenderer);
|
|
14366
|
+
state.internal.actualRenderer = renderer;
|
|
14367
|
+
state.set({ isLegacy: true, gl: renderer, renderer, primaryStore: store });
|
|
14368
|
+
}
|
|
14369
|
+
})().catch((err) => {
|
|
14370
|
+
rendererSetup = null;
|
|
14371
|
+
throw err;
|
|
14372
|
+
});
|
|
14373
|
+
}
|
|
14374
|
+
await rendererSetup;
|
|
14375
|
+
state = store.getState();
|
|
14376
|
+
renderer = state.internal.actualRenderer;
|
|
14222
14377
|
}
|
|
14223
14378
|
let raycaster = state.raycaster;
|
|
14224
14379
|
if (!raycaster) state.set({ raycaster: raycaster = new three.Raycaster() });
|
|
@@ -14568,7 +14723,8 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14568
14723
|
dispose(state.scene);
|
|
14569
14724
|
_roots.delete(canvas);
|
|
14570
14725
|
if (callback) callback(canvas);
|
|
14571
|
-
} catch {
|
|
14726
|
+
} catch (error) {
|
|
14727
|
+
console.warn("[R3F] Error while unmounting root; teardown may be incomplete:", error);
|
|
14572
14728
|
}
|
|
14573
14729
|
}, 500);
|
|
14574
14730
|
}
|
|
@@ -14631,6 +14787,7 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
14631
14787
|
viewport = rootState.viewport.getCurrentViewport(camera, new three.Vector3(), resolvedSize);
|
|
14632
14788
|
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
14633
14789
|
}
|
|
14790
|
+
const set = injectState.set;
|
|
14634
14791
|
return {
|
|
14635
14792
|
// The intersect consists of the previous root state
|
|
14636
14793
|
...rootState,
|
|
@@ -14649,7 +14806,7 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
14649
14806
|
size: resolvedSize,
|
|
14650
14807
|
viewport: { ...rootState.viewport, ...viewport },
|
|
14651
14808
|
// Layers are allowed to override events
|
|
14652
|
-
setEvents: (events2) =>
|
|
14809
|
+
setEvents: (events2) => set((state2) => ({ ...state2, events: { ...state2.events, ...events2 } })),
|
|
14653
14810
|
// Container for child attachment - the portalScene (injected or container itself)
|
|
14654
14811
|
internal: { ...rootState.internal, ...injectState.internal, container: portalScene }
|
|
14655
14812
|
};
|
|
@@ -14708,14 +14865,49 @@ function parseBackground(background) {
|
|
|
14708
14865
|
return null;
|
|
14709
14866
|
}
|
|
14710
14867
|
|
|
14868
|
+
function parseRendererConfig(rendererProp) {
|
|
14869
|
+
const isRendererConfig = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp);
|
|
14870
|
+
if (isRendererConfig) {
|
|
14871
|
+
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
14872
|
+
return {
|
|
14873
|
+
primaryCanvas: pc,
|
|
14874
|
+
scheduler: sc,
|
|
14875
|
+
renderer: Object.keys(rest).length > 0 ? rest : rendererProp
|
|
14876
|
+
};
|
|
14877
|
+
}
|
|
14878
|
+
return { primaryCanvas: void 0, scheduler: void 0, renderer: rendererProp };
|
|
14879
|
+
}
|
|
14880
|
+
|
|
14881
|
+
const RESOURCE_KINDS = ["nodes", "uniforms", "buffers", "gpuStorage"];
|
|
14882
|
+
const registries = /* @__PURE__ */ new WeakMap();
|
|
14883
|
+
function getKindRegistry(store, kind) {
|
|
14884
|
+
let registry = registries.get(store);
|
|
14885
|
+
if (!registry) {
|
|
14886
|
+
registry = {
|
|
14887
|
+
nodes: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14888
|
+
uniforms: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14889
|
+
buffers: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14890
|
+
gpuStorage: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() }
|
|
14891
|
+
};
|
|
14892
|
+
registries.set(store, registry);
|
|
14893
|
+
}
|
|
14894
|
+
return registry[kind];
|
|
14895
|
+
}
|
|
14896
|
+
function invalidateResource(store, kind, scopeKey) {
|
|
14897
|
+
const registry = getKindRegistry(store, kind);
|
|
14898
|
+
{
|
|
14899
|
+
registry.valid.clear();
|
|
14900
|
+
registry.staged.clear();
|
|
14901
|
+
}
|
|
14902
|
+
}
|
|
14903
|
+
function invalidateAllResources(store) {
|
|
14904
|
+
for (const kind of RESOURCE_KINDS) invalidateResource(store, kind);
|
|
14905
|
+
}
|
|
14906
|
+
|
|
14711
14907
|
function clearHmrCaches(store) {
|
|
14712
|
-
store.
|
|
14713
|
-
|
|
14714
|
-
|
|
14715
|
-
buffers: {},
|
|
14716
|
-
gpuStorage: {},
|
|
14717
|
-
_hmrVersion: state._hmrVersion + 1
|
|
14718
|
-
}));
|
|
14908
|
+
const primary = store.getState().primaryStore ?? store;
|
|
14909
|
+
invalidateAllResources(primary);
|
|
14910
|
+
primary.setState((state) => ({ _hmrVersion: state._hmrVersion + 1 }));
|
|
14719
14911
|
}
|
|
14720
14912
|
|
|
14721
14913
|
function CanvasImpl({
|
|
@@ -14751,18 +14943,7 @@ function CanvasImpl({
|
|
|
14751
14943
|
forceEven,
|
|
14752
14944
|
...props
|
|
14753
14945
|
}) {
|
|
14754
|
-
const
|
|
14755
|
-
let primaryCanvas;
|
|
14756
|
-
let scheduler;
|
|
14757
|
-
let renderer;
|
|
14758
|
-
if (isRendererConfig) {
|
|
14759
|
-
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
14760
|
-
primaryCanvas = pc;
|
|
14761
|
-
scheduler = sc;
|
|
14762
|
-
renderer = Object.keys(rest).length > 0 ? rest : rendererProp;
|
|
14763
|
-
} else {
|
|
14764
|
-
renderer = rendererProp;
|
|
14765
|
-
}
|
|
14946
|
+
const { primaryCanvas, scheduler, renderer } = parseRendererConfig(rendererProp);
|
|
14766
14947
|
React__namespace.useMemo(() => extend(THREE), []);
|
|
14767
14948
|
const Bridge = useBridge();
|
|
14768
14949
|
const backgroundProps = React__namespace.useMemo(() => parseBackground(background), [background]);
|
|
@@ -14807,6 +14988,7 @@ function CanvasImpl({
|
|
|
14807
14988
|
const handleDropMissed = useMutableCallback(onDropMissed);
|
|
14808
14989
|
const [block, setBlock] = React__namespace.useState(false);
|
|
14809
14990
|
const [error, setError] = React__namespace.useState(false);
|
|
14991
|
+
const [fallbackVisible, setFallbackVisible] = React__namespace.useState(false);
|
|
14810
14992
|
if (block) throw block;
|
|
14811
14993
|
if (error) throw error;
|
|
14812
14994
|
const root = React__namespace.useRef(null);
|
|
@@ -14814,6 +14996,7 @@ function CanvasImpl({
|
|
|
14814
14996
|
const unsubscribeErrorRef = React__namespace.useRef(null);
|
|
14815
14997
|
useIsomorphicLayoutEffect(() => {
|
|
14816
14998
|
effectActiveRef.current = true;
|
|
14999
|
+
if (fallbackVisible) return;
|
|
14817
15000
|
const canvas = canvasRef.current;
|
|
14818
15001
|
if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
|
|
14819
15002
|
if (!root.current) {
|
|
@@ -14834,7 +15017,7 @@ function CanvasImpl({
|
|
|
14834
15017
|
}
|
|
14835
15018
|
async function run() {
|
|
14836
15019
|
if (!effectActiveRef.current || !root.current) return;
|
|
14837
|
-
await root.current.configure({
|
|
15020
|
+
const configured = await root.current.configure({
|
|
14838
15021
|
id,
|
|
14839
15022
|
primaryCanvas,
|
|
14840
15023
|
scheduler,
|
|
@@ -14875,8 +15058,20 @@ function CanvasImpl({
|
|
|
14875
15058
|
}
|
|
14876
15059
|
onCreated?.(state);
|
|
14877
15060
|
}
|
|
14878
|
-
})
|
|
14879
|
-
|
|
15061
|
+
}).then(
|
|
15062
|
+
() => true,
|
|
15063
|
+
// Renderer setup failed (e.g. no WebGL/WebGPU support). The `fallback` prop lives
|
|
15064
|
+
// inside <canvas>, which browsers don't display, so surface it as visible DOM
|
|
15065
|
+
// instead; with no fallback, rethrow to an external error boundary. (#3757)
|
|
15066
|
+
(setupError) => {
|
|
15067
|
+
if (effectActiveRef.current) {
|
|
15068
|
+
if (fallback != null) setFallbackVisible(true);
|
|
15069
|
+
else setError(setupError);
|
|
15070
|
+
}
|
|
15071
|
+
return false;
|
|
15072
|
+
}
|
|
15073
|
+
);
|
|
15074
|
+
if (!configured || !effectActiveRef.current || !root.current) return;
|
|
14880
15075
|
root.current.render(
|
|
14881
15076
|
/* @__PURE__ */ jsxRuntime.jsx(Bridge, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(Block, { set: setBlock }), children: [
|
|
14882
15077
|
backgroundProps && /* @__PURE__ */ jsxRuntime.jsx(Environment, { ...backgroundProps }),
|
|
@@ -14939,7 +15134,11 @@ function CanvasImpl({
|
|
|
14939
15134
|
...style
|
|
14940
15135
|
},
|
|
14941
15136
|
...props,
|
|
14942
|
-
children:
|
|
15137
|
+
children: fallbackVisible ? (
|
|
15138
|
+
// Renderer setup failed: render the fallback as visible DOM. Inside <canvas> (below)
|
|
15139
|
+
// it exists in the tree but browsers never paint it, which is the whole bug (#3757).
|
|
15140
|
+
fallback
|
|
15141
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
14943
15142
|
"canvas",
|
|
14944
15143
|
{
|
|
14945
15144
|
ref: canvasRef,
|