@react-three/fiber 10.0.0-canary.b86abaa → 10.0.0-canary.b9d5979
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/extension.d.cts +3 -3
- package/dist/extension.d.mts +3 -3
- package/dist/extension.d.ts +3 -3
- package/dist/extension.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.mjs +3 -3
- package/dist/legacy.cjs +1 -1
- package/dist/legacy.d.cts +4 -4
- package/dist/legacy.d.mts +4 -4
- package/dist/legacy.d.ts +4 -4
- package/dist/legacy.mjs +4 -4
- package/dist/shared/{fiber.tsM9NKZ9.mjs → fiber.5Q8N6Hhq.mjs} +226 -57
- package/dist/shared/{fiber.Cx-UAmMb.d.ts → fiber.B_GGVI86.d.ts} +1 -1
- package/dist/shared/{fiber.DXw-SLsH.d.ts → fiber.BcNm6NAg.d.cts} +88 -4
- package/dist/shared/{fiber.oKEFddXj.cjs → fiber.BegWBc5_.cjs} +226 -57
- package/dist/shared/{fiber.BY6Yf1h-.d.cts → fiber.CQDCACCJ.d.mts} +88 -4
- package/dist/shared/{fiber.B0oukOFO.mjs → fiber.CUKAa7Rv.mjs} +1 -1
- package/dist/shared/{fiber.I5Q4dVvl.d.cts → fiber.CZLeHcML.d.cts} +24 -2
- package/dist/shared/{fiber.I5Q4dVvl.d.mts → fiber.CZLeHcML.d.mts} +24 -2
- package/dist/shared/{fiber.I5Q4dVvl.d.ts → fiber.CZLeHcML.d.ts} +24 -2
- package/dist/shared/{fiber.BU0vBHc9.d.mts → fiber.ColkapKS.d.mts} +1 -1
- package/dist/shared/{fiber.DAl4H27x.d.cts → fiber.DRfTw2kk.d.cts} +1 -1
- package/dist/shared/{fiber.Cu2hX1IM.d.mts → fiber.DeBIf2pk.d.ts} +88 -4
- package/dist/webgpu/index.cjs +1 -1
- package/dist/webgpu/index.d.cts +4 -4
- package/dist/webgpu/index.d.mts +4 -4
- package/dist/webgpu/index.d.ts +4 -4
- package/dist/webgpu/index.mjs +4 -4
- package/package.json +1 -1
|
@@ -417,6 +417,15 @@ function isOnce(value) {
|
|
|
417
417
|
return value !== null && typeof value === "object" && ONCE in value;
|
|
418
418
|
}
|
|
419
419
|
|
|
420
|
+
function assertNodeMaterialSupported(state, value) {
|
|
421
|
+
if (!state?.isLegacy) return;
|
|
422
|
+
const material = (Array.isArray(value) ? value : [value]).find((m) => m?.isNodeMaterial);
|
|
423
|
+
if (!material) return;
|
|
424
|
+
throw new Error(
|
|
425
|
+
`R3F: ${material.type ?? "Node material"} requires WebGPURenderer (it falls back to WebGL2 automatically). Pass \`renderer\` to <Canvas> from @react-three/fiber, or import from @react-three/fiber/webgpu.`
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
|
|
420
429
|
const RESERVED_PROPS = [
|
|
421
430
|
"children",
|
|
422
431
|
"key",
|
|
@@ -587,6 +596,7 @@ function applyProps(object, props) {
|
|
|
587
596
|
}
|
|
588
597
|
}
|
|
589
598
|
} else {
|
|
599
|
+
if (key === "material") assertNodeMaterialSupported(rootState, value);
|
|
590
600
|
root[key] = value;
|
|
591
601
|
if (key.endsWith("Node") && root.isMaterial) {
|
|
592
602
|
root.needsUpdate = true;
|
|
@@ -13900,11 +13910,16 @@ function validateInstance(type, props, root) {
|
|
|
13900
13910
|
const name = toPascalCase(type);
|
|
13901
13911
|
const target = resolveConstructor(name, root);
|
|
13902
13912
|
if (type !== "primitive" && !target) {
|
|
13913
|
+
if (name.endsWith("NodeMaterial")) {
|
|
13914
|
+
assertNodeMaterialSupported(root.getState(), { isNodeMaterial: true, type: name });
|
|
13915
|
+
}
|
|
13903
13916
|
throw new Error(
|
|
13904
13917
|
`R3F: ${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`
|
|
13905
13918
|
);
|
|
13906
13919
|
}
|
|
13907
13920
|
if (type === "primitive" && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`);
|
|
13921
|
+
assertNodeMaterialSupported(root.getState(), props.object);
|
|
13922
|
+
assertNodeMaterialSupported(root.getState(), props.material);
|
|
13908
13923
|
if (props.args !== void 0 && !Array.isArray(props.args)) throw new Error("R3F: The args prop must be an array!");
|
|
13909
13924
|
}
|
|
13910
13925
|
function createInstance(type, props, root) {
|
|
@@ -14003,6 +14018,7 @@ function disposeOnIdle(object) {
|
|
|
14003
14018
|
}
|
|
14004
14019
|
function removeChild(parent, child, dispose) {
|
|
14005
14020
|
if (!child) return;
|
|
14021
|
+
const wasLinked = !!child.parent;
|
|
14006
14022
|
child.parent = null;
|
|
14007
14023
|
const childIndex = parent.children.indexOf(child);
|
|
14008
14024
|
if (childIndex !== -1) parent.children.splice(childIndex, 1);
|
|
@@ -14022,7 +14038,10 @@ function removeChild(parent, child, dispose) {
|
|
|
14022
14038
|
if (shouldDispose && child.type !== "primitive" && child.object.type !== "Scene") {
|
|
14023
14039
|
disposeOnIdle(child.object);
|
|
14024
14040
|
}
|
|
14025
|
-
if (dispose === void 0)
|
|
14041
|
+
if (dispose === void 0 && wasLinked) {
|
|
14042
|
+
const state = findInitialRoot(child).getState();
|
|
14043
|
+
if (state.internal.active && state.internal.frames === 0) state.invalidate();
|
|
14044
|
+
}
|
|
14026
14045
|
}
|
|
14027
14046
|
function setFiberRef(fiber, publicInstance) {
|
|
14028
14047
|
for (const _fiber of [fiber, fiber.alternate]) {
|
|
@@ -14771,6 +14790,69 @@ function getPrimaryIds() {
|
|
|
14771
14790
|
return Array.from(primaryRegistry.keys());
|
|
14772
14791
|
}
|
|
14773
14792
|
|
|
14793
|
+
const fulfilled = (value) => Object.assign(Promise.resolve(value), { status: "fulfilled", value });
|
|
14794
|
+
const tracked = (promise) => {
|
|
14795
|
+
const result = Promise.resolve(promise);
|
|
14796
|
+
result.status = "pending";
|
|
14797
|
+
result.then(
|
|
14798
|
+
(value) => {
|
|
14799
|
+
Object.assign(result, { status: "fulfilled", value });
|
|
14800
|
+
},
|
|
14801
|
+
(reason) => {
|
|
14802
|
+
Object.assign(result, { status: "rejected", reason });
|
|
14803
|
+
}
|
|
14804
|
+
);
|
|
14805
|
+
return result;
|
|
14806
|
+
};
|
|
14807
|
+
|
|
14808
|
+
const records = /* @__PURE__ */ new WeakMap();
|
|
14809
|
+
function take(renderer, record) {
|
|
14810
|
+
record.leases++;
|
|
14811
|
+
let released = false;
|
|
14812
|
+
return () => {
|
|
14813
|
+
if (released) return;
|
|
14814
|
+
released = true;
|
|
14815
|
+
if (--record.leases > 0) return;
|
|
14816
|
+
records.delete(renderer);
|
|
14817
|
+
if (record.owned) return disposeRenderer(renderer);
|
|
14818
|
+
};
|
|
14819
|
+
}
|
|
14820
|
+
function leaseRenderer(renderer, owned) {
|
|
14821
|
+
let record = records.get(renderer);
|
|
14822
|
+
if (!record) records.set(renderer, record = { owned, leases: 0 });
|
|
14823
|
+
return take(renderer, record);
|
|
14824
|
+
}
|
|
14825
|
+
function borrowRenderer(renderer) {
|
|
14826
|
+
const record = records.get(renderer);
|
|
14827
|
+
if (!record) throw new Error("R3F: cannot share a renderer whose canvas has already unmounted");
|
|
14828
|
+
return take(renderer, record);
|
|
14829
|
+
}
|
|
14830
|
+
function disposeRenderer(renderer) {
|
|
14831
|
+
if (renderer.hasInitialized?.() === false) return;
|
|
14832
|
+
const warn = (error) => console.warn("[R3F] Error disposing renderer", error);
|
|
14833
|
+
const loseContext = () => {
|
|
14834
|
+
try {
|
|
14835
|
+
;
|
|
14836
|
+
renderer.forceContextLoss?.();
|
|
14837
|
+
} catch (error) {
|
|
14838
|
+
warn(error);
|
|
14839
|
+
}
|
|
14840
|
+
};
|
|
14841
|
+
let disposed;
|
|
14842
|
+
try {
|
|
14843
|
+
disposed = renderer.dispose();
|
|
14844
|
+
} catch (error) {
|
|
14845
|
+
warn(error);
|
|
14846
|
+
}
|
|
14847
|
+
if (typeof disposed?.then === "function") {
|
|
14848
|
+
return Promise.resolve(disposed).then(loseContext, (error) => {
|
|
14849
|
+
warn(error);
|
|
14850
|
+
loseContext();
|
|
14851
|
+
});
|
|
14852
|
+
}
|
|
14853
|
+
loseContext();
|
|
14854
|
+
}
|
|
14855
|
+
|
|
14774
14856
|
const isRenderer = (def) => !!def?.render;
|
|
14775
14857
|
const _roots = /* @__PURE__ */ new Map();
|
|
14776
14858
|
function ensureStoreThreeObjects(store) {
|
|
@@ -14782,9 +14864,9 @@ function ensureStoreThreeObjects(store) {
|
|
|
14782
14864
|
}
|
|
14783
14865
|
const shallowLoose = { objects: "shallow", strict: false };
|
|
14784
14866
|
async function resolveRenderer(config, defaultProps, RendererClass) {
|
|
14785
|
-
if (typeof config === "function") return await config(defaultProps);
|
|
14786
|
-
if (isRenderer(config)) return config;
|
|
14787
|
-
return new RendererClass({ ...defaultProps, ...config });
|
|
14867
|
+
if (typeof config === "function") return { renderer: await config(defaultProps), owned: true };
|
|
14868
|
+
if (isRenderer(config)) return { renderer: config, owned: false };
|
|
14869
|
+
return { renderer: new RendererClass({ ...defaultProps, ...config }), owned: true };
|
|
14788
14870
|
}
|
|
14789
14871
|
function computeInitialSize(canvas, size) {
|
|
14790
14872
|
if (!size && typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement && canvas.parentElement) {
|
|
@@ -14800,6 +14882,34 @@ function computeInitialSize(canvas, size) {
|
|
|
14800
14882
|
}
|
|
14801
14883
|
return { width: 0, height: 0, top: 0, left: 0, ...size };
|
|
14802
14884
|
}
|
|
14885
|
+
function watchDpr(onChange) {
|
|
14886
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function" || !window.devicePixelRatio) {
|
|
14887
|
+
return () => {
|
|
14888
|
+
};
|
|
14889
|
+
}
|
|
14890
|
+
let query;
|
|
14891
|
+
const listen = () => {
|
|
14892
|
+
try {
|
|
14893
|
+
query = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
14894
|
+
if (typeof query?.addEventListener === "function") query.addEventListener("change", handleChange);
|
|
14895
|
+
else query?.addListener?.(handleChange);
|
|
14896
|
+
} catch {
|
|
14897
|
+
query = void 0;
|
|
14898
|
+
}
|
|
14899
|
+
};
|
|
14900
|
+
const unlisten = () => {
|
|
14901
|
+
if (typeof query?.removeEventListener === "function") query.removeEventListener("change", handleChange);
|
|
14902
|
+
else query?.removeListener?.(handleChange);
|
|
14903
|
+
query = void 0;
|
|
14904
|
+
};
|
|
14905
|
+
const handleChange = () => {
|
|
14906
|
+
unlisten();
|
|
14907
|
+
listen();
|
|
14908
|
+
onChange();
|
|
14909
|
+
};
|
|
14910
|
+
listen();
|
|
14911
|
+
return unlisten;
|
|
14912
|
+
}
|
|
14803
14913
|
function createRoot(canvas, provider) {
|
|
14804
14914
|
const prevRoot = _roots.get(canvas);
|
|
14805
14915
|
const prevFiber = prevRoot?.fiber;
|
|
@@ -14836,15 +14946,39 @@ function createRoot(canvas, provider) {
|
|
|
14836
14946
|
null
|
|
14837
14947
|
// transitionCallbacks
|
|
14838
14948
|
);
|
|
14839
|
-
|
|
14949
|
+
const root = prevRoot || { fiber, store, unmountClaim: null, ready: fulfilled(void 0) };
|
|
14950
|
+
if (!prevRoot) _roots.set(canvas, root);
|
|
14840
14951
|
let onCreated;
|
|
14841
14952
|
let lastCamera;
|
|
14842
14953
|
const lastConfiguredProps = {};
|
|
14954
|
+
let resolvedDpr = 0;
|
|
14955
|
+
let dprChangedInXR = false;
|
|
14956
|
+
let unwatchDpr;
|
|
14957
|
+
const resolveDpr = () => {
|
|
14958
|
+
if (_roots.get(canvas)?.store !== store) return unwatchDpr?.();
|
|
14959
|
+
const state = store.getState();
|
|
14960
|
+
const xr = state.internal.actualRenderer?.xr;
|
|
14961
|
+
if (xr?.isPresenting || xr?.getSession?.()) {
|
|
14962
|
+
dprChangedInXR = true;
|
|
14963
|
+
return;
|
|
14964
|
+
}
|
|
14965
|
+
dprChangedInXR = false;
|
|
14966
|
+
const dpr = lastConfiguredProps.dpr;
|
|
14967
|
+
if (dpr === void 0 || state.viewport.dpr !== resolvedDpr || calculateDpr(dpr) === resolvedDpr) return;
|
|
14968
|
+
state.setDpr(dpr);
|
|
14969
|
+
resolvedDpr = store.getState().viewport.dpr;
|
|
14970
|
+
};
|
|
14843
14971
|
let configured = false;
|
|
14844
14972
|
let pending = null;
|
|
14845
|
-
|
|
14973
|
+
const cancelUnmount = () => {
|
|
14974
|
+
if (!root.unmountClaim) return;
|
|
14975
|
+
root.unmountClaim = null;
|
|
14976
|
+
store.getState().internal.active = true;
|
|
14977
|
+
};
|
|
14846
14978
|
return {
|
|
14847
14979
|
async configure(props = {}) {
|
|
14980
|
+
if (_roots.get(canvas) !== root) throw new Error("R3F: cannot configure a root after it has unmounted");
|
|
14981
|
+
cancelUnmount();
|
|
14848
14982
|
let resolve;
|
|
14849
14983
|
pending = new Promise((_resolve) => resolve = _resolve);
|
|
14850
14984
|
const {
|
|
@@ -14918,20 +15052,23 @@ function createRoot(canvas, provider) {
|
|
|
14918
15052
|
);
|
|
14919
15053
|
}
|
|
14920
15054
|
if (!state.internal.actualRenderer) {
|
|
14921
|
-
if (
|
|
14922
|
-
|
|
15055
|
+
if (root.ready.status !== "pending") {
|
|
15056
|
+
const setup = (async () => {
|
|
14923
15057
|
const support = wantsGL ? await webgl() : await webgpu();
|
|
14924
15058
|
registerThree(support.three);
|
|
14925
15059
|
state.internal.support = support;
|
|
14926
15060
|
ensureStoreThreeObjects(store);
|
|
14927
15061
|
if (support.kind === "webgl") {
|
|
14928
|
-
|
|
15062
|
+
const resolved = await resolveRenderer(glConfig, defaultGLProps, support.Renderer);
|
|
15063
|
+
renderer = resolved.renderer;
|
|
14929
15064
|
state.internal.actualRenderer = renderer;
|
|
15065
|
+
state.internal.releaseRenderer = leaseRenderer(renderer, resolved.owned);
|
|
14930
15066
|
state.set({ isLegacy: true, gl: renderer, renderer, primaryStore: store });
|
|
14931
15067
|
} else if (primaryCanvas) {
|
|
14932
15068
|
const primary = await waitForPrimary(primaryCanvas);
|
|
14933
15069
|
renderer = primary.renderer;
|
|
14934
15070
|
state.internal.actualRenderer = renderer;
|
|
15071
|
+
state.internal.releaseRenderer = borrowRenderer(renderer);
|
|
14935
15072
|
const canvasTarget = new support.CanvasTarget(canvas);
|
|
14936
15073
|
primary.store.setState((prev) => ({
|
|
14937
15074
|
internal: { ...prev.internal, isMultiCanvas: true }
|
|
@@ -14949,7 +15086,8 @@ function createRoot(canvas, provider) {
|
|
|
14949
15086
|
}
|
|
14950
15087
|
}));
|
|
14951
15088
|
} else {
|
|
14952
|
-
|
|
15089
|
+
const resolved = await resolveRenderer(rendererConfig, defaultGPUProps, support.Renderer);
|
|
15090
|
+
renderer = resolved.renderer;
|
|
14953
15091
|
if (!renderer.hasInitialized?.()) {
|
|
14954
15092
|
const size2 = computeInitialSize(canvas, propsSize);
|
|
14955
15093
|
if (size2.width > 0 && size2.height > 0) {
|
|
@@ -14961,6 +15099,7 @@ function createRoot(canvas, provider) {
|
|
|
14961
15099
|
const backend = renderer.backend;
|
|
14962
15100
|
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
14963
15101
|
state.internal.actualRenderer = renderer;
|
|
15102
|
+
state.internal.releaseRenderer = leaseRenderer(renderer, resolved.owned);
|
|
14964
15103
|
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
14965
15104
|
if (canvasId && !state.internal.isSecondary) {
|
|
14966
15105
|
const canvasTarget = renderer.getCanvasTarget?.();
|
|
@@ -14974,12 +15113,10 @@ function createRoot(canvas, provider) {
|
|
|
14974
15113
|
}));
|
|
14975
15114
|
}
|
|
14976
15115
|
}
|
|
14977
|
-
})()
|
|
14978
|
-
|
|
14979
|
-
throw err;
|
|
14980
|
-
});
|
|
15116
|
+
})();
|
|
15117
|
+
root.ready = tracked(setup);
|
|
14981
15118
|
}
|
|
14982
|
-
await
|
|
15119
|
+
await root.ready;
|
|
14983
15120
|
state = store.getState();
|
|
14984
15121
|
renderer = state.internal.actualRenderer;
|
|
14985
15122
|
}
|
|
@@ -15058,6 +15195,12 @@ function createRoot(canvas, provider) {
|
|
|
15058
15195
|
if (dpr !== void 0 && !is.equ(dpr, lastConfiguredProps.dpr, shallowLoose)) {
|
|
15059
15196
|
state.setDpr(dpr);
|
|
15060
15197
|
lastConfiguredProps.dpr = dpr;
|
|
15198
|
+
resolvedDpr = store.getState().viewport.dpr;
|
|
15199
|
+
}
|
|
15200
|
+
const internal = store.getState().internal;
|
|
15201
|
+
if (Array.isArray(dpr) && (!unwatchDpr || internal.unwatchDpr !== unwatchDpr)) {
|
|
15202
|
+
internal.unwatchDpr?.();
|
|
15203
|
+
internal.unwatchDpr = unwatchDpr = watchDpr(resolveDpr);
|
|
15061
15204
|
}
|
|
15062
15205
|
if (frameloop !== void 0 && frameloop !== lastConfiguredProps.frameloop) {
|
|
15063
15206
|
state.setFrameloop(frameloop);
|
|
@@ -15086,7 +15229,10 @@ function createRoot(canvas, provider) {
|
|
|
15086
15229
|
const renderer2 = state2.internal.actualRenderer;
|
|
15087
15230
|
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
15088
15231
|
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
15089
|
-
if (!renderer2.xr.isPresenting)
|
|
15232
|
+
if (!renderer2.xr.isPresenting) {
|
|
15233
|
+
if (dprChangedInXR) resolveDpr();
|
|
15234
|
+
invalidate(state2);
|
|
15235
|
+
}
|
|
15090
15236
|
};
|
|
15091
15237
|
const xr = {
|
|
15092
15238
|
connect() {
|
|
@@ -15296,8 +15442,11 @@ function createRoot(canvas, provider) {
|
|
|
15296
15442
|
return this;
|
|
15297
15443
|
},
|
|
15298
15444
|
render(children) {
|
|
15445
|
+
if (_roots.get(canvas) !== root) return store;
|
|
15446
|
+
cancelUnmount();
|
|
15299
15447
|
if (!configured && !pending) this.configure();
|
|
15300
15448
|
pending.then(() => {
|
|
15449
|
+
if (_roots.get(canvas) !== root || root.unmountClaim) return;
|
|
15301
15450
|
reconciler.updateContainer(
|
|
15302
15451
|
/* @__PURE__ */ jsxRuntime.jsx(Provider, { store, children, onCreated, rootElement: canvas }),
|
|
15303
15452
|
fiber,
|
|
@@ -15308,7 +15457,7 @@ function createRoot(canvas, provider) {
|
|
|
15308
15457
|
return store;
|
|
15309
15458
|
},
|
|
15310
15459
|
unmount() {
|
|
15311
|
-
unmountComponentAtNode(canvas);
|
|
15460
|
+
if (_roots.get(canvas) === root) unmountComponentAtNode(canvas);
|
|
15312
15461
|
}
|
|
15313
15462
|
};
|
|
15314
15463
|
}
|
|
@@ -15328,46 +15477,52 @@ function Provider({
|
|
|
15328
15477
|
}
|
|
15329
15478
|
function unmountComponentAtNode(canvas, callback) {
|
|
15330
15479
|
const root = _roots.get(canvas);
|
|
15331
|
-
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
|
|
15336
|
-
|
|
15337
|
-
if (
|
|
15338
|
-
|
|
15339
|
-
|
|
15480
|
+
if (!root) return;
|
|
15481
|
+
const claim = root.unmountClaim = Symbol("unmount");
|
|
15482
|
+
root.store.getState().internal.active = false;
|
|
15483
|
+
reconciler.updateContainer(null, root.fiber, null, () => {
|
|
15484
|
+
if (root.unmountClaim !== claim) return;
|
|
15485
|
+
reconciler.updateContainer(null, root.fiber, null, () => {
|
|
15486
|
+
if (root.unmountClaim !== claim) return;
|
|
15487
|
+
if (root.ready.status === "pending") root.ready.then(teardown, teardown);
|
|
15488
|
+
else teardown();
|
|
15489
|
+
});
|
|
15490
|
+
});
|
|
15491
|
+
function teardown() {
|
|
15492
|
+
if (root.unmountClaim !== claim) return;
|
|
15493
|
+
root.unmountClaim = null;
|
|
15494
|
+
_roots.delete(canvas);
|
|
15495
|
+
const state = root.store.getState();
|
|
15496
|
+
const internal = state.internal;
|
|
15497
|
+
internal.active = false;
|
|
15498
|
+
const attempt = (step) => {
|
|
15499
|
+
try {
|
|
15500
|
+
return step();
|
|
15501
|
+
} catch (error) {
|
|
15502
|
+
console.warn("[R3F] Error while unmounting root; teardown may be incomplete:", error);
|
|
15340
15503
|
}
|
|
15341
|
-
}
|
|
15342
|
-
|
|
15343
|
-
|
|
15344
|
-
|
|
15345
|
-
|
|
15346
|
-
|
|
15347
|
-
|
|
15348
|
-
|
|
15349
|
-
|
|
15350
|
-
|
|
15351
|
-
|
|
15352
|
-
|
|
15353
|
-
|
|
15354
|
-
|
|
15355
|
-
|
|
15356
|
-
|
|
15357
|
-
|
|
15358
|
-
|
|
15359
|
-
|
|
15360
|
-
|
|
15361
|
-
}
|
|
15362
|
-
dispose(state.scene);
|
|
15363
|
-
_roots.delete(canvas);
|
|
15364
|
-
if (callback) callback(canvas);
|
|
15365
|
-
} catch (error) {
|
|
15366
|
-
console.warn("[R3F] Error while unmounting root; teardown may be incomplete:", error);
|
|
15367
|
-
}
|
|
15368
|
-
}, 500);
|
|
15504
|
+
};
|
|
15505
|
+
attempt(() => internal.unwatchDpr?.());
|
|
15506
|
+
internal.unwatchDpr = void 0;
|
|
15507
|
+
attempt(() => internal.unregisterRoot?.());
|
|
15508
|
+
internal.unregisterRoot = void 0;
|
|
15509
|
+
attempt(() => extensions.detachRootExtensions(root.store));
|
|
15510
|
+
attempt(() => internal.unregisterPrimary?.());
|
|
15511
|
+
attempt(() => state.events.disconnect?.());
|
|
15512
|
+
if (!internal.isSecondary && internal.actualRenderer?.xr && state.xr) attempt(() => state.xr.disconnect());
|
|
15513
|
+
attempt(() => cleanupHelperGroup(root.store));
|
|
15514
|
+
if (state.scene) attempt(() => dispose(state.scene));
|
|
15515
|
+
const canvasTarget = internal.canvasTarget;
|
|
15516
|
+
if (internal.isSecondary && canvasTarget?.dispose) attempt(() => canvasTarget.dispose());
|
|
15517
|
+
const released = attempt(() => internal.releaseRenderer?.());
|
|
15518
|
+
internal.releaseRenderer = void 0;
|
|
15519
|
+
if (callback) {
|
|
15520
|
+
if (released) {
|
|
15521
|
+
released.then(() => callback(canvas)).catch((error) => console.warn("[R3F] Error in unmount callback", error));
|
|
15522
|
+
} else {
|
|
15523
|
+
callback(canvas);
|
|
15369
15524
|
}
|
|
15370
|
-
}
|
|
15525
|
+
}
|
|
15371
15526
|
}
|
|
15372
15527
|
}
|
|
15373
15528
|
function createPortal(children, container, state) {
|
|
@@ -15912,13 +16067,27 @@ function CanvasImpl({
|
|
|
15912
16067
|
}
|
|
15913
16068
|
};
|
|
15914
16069
|
});
|
|
16070
|
+
const insertionMounted = React__namespace.useRef(false);
|
|
16071
|
+
React__namespace.useInsertionEffect(() => {
|
|
16072
|
+
insertionMounted.current = true;
|
|
16073
|
+
return () => {
|
|
16074
|
+
insertionMounted.current = false;
|
|
16075
|
+
queueMicrotask(() => {
|
|
16076
|
+
if (insertionMounted.current) return;
|
|
16077
|
+
const current = root.current;
|
|
16078
|
+
root.current = null;
|
|
16079
|
+
current?.unmount();
|
|
16080
|
+
});
|
|
16081
|
+
};
|
|
16082
|
+
}, []);
|
|
15915
16083
|
React__namespace.useEffect(() => {
|
|
15916
16084
|
const canvas = canvasRef.current;
|
|
15917
16085
|
if (canvas) {
|
|
15918
16086
|
return () => {
|
|
15919
16087
|
if (canvas.isConnected) return;
|
|
15920
|
-
|
|
16088
|
+
const current = root.current;
|
|
15921
16089
|
root.current = null;
|
|
16090
|
+
current?.unmount();
|
|
15922
16091
|
};
|
|
15923
16092
|
}
|
|
15924
16093
|
}, []);
|
|
@@ -15932,7 +16101,7 @@ function CanvasImpl({
|
|
|
15932
16101
|
if (rootEntry?.store) extensions.notifyRootExtensionsHmr(rootEntry.store);
|
|
15933
16102
|
});
|
|
15934
16103
|
};
|
|
15935
|
-
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/fiber.
|
|
16104
|
+
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/fiber.BegWBc5_.cjs', document.baseURI).href)) }) !== "undefined" && undefined) {
|
|
15936
16105
|
const hot = undefined;
|
|
15937
16106
|
hot.on("vite:afterUpdate", handleHMR);
|
|
15938
16107
|
return () => hot.off?.("vite:afterUpdate", handleHMR);
|
|
@@ -3,7 +3,7 @@ import { ReactNode, Component, RefObject, JSX } from 'react';
|
|
|
3
3
|
import { Options } from 'react-use-measure';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
5
|
import { ColorRepresentation, Euler as Euler$1, Loader, RenderTargetOptions as RenderTargetOptions$1, ColorSpace, Texture as Texture$1, CubeTexture, Scene, Object3D } from 'three';
|
|
6
|
-
import {
|
|
6
|
+
import { K as Properties, c as Size, F as Frameloop, e as Performance, D as Dpr, g as RootStore, p as EventManager, f as RootState, n as ComputeFunction, C as ConstructorRepresentation, $ as ObjectMap, I as InternalState, M as Mutable, O as Overwrite, z as Args, l as EventHandlers, G as InstanceProps, k as DomEvent, H as Instance, y as Catalogue, w as Root, a7 as ThreeCore, Y as Bridge, _ as UnblockProps, a1 as Disposable, U as ThreeCamera, a0 as EquConfig } from './fiber.CZLeHcML.mjs';
|
|
7
7
|
import { WebGPURenderer, WebGPURendererParameters } from 'three/webgpu';
|
|
8
8
|
|
|
9
9
|
//* Base Renderer Types =====================================
|
|
@@ -155,8 +155,11 @@ interface RenderProps<TCanvas extends HTMLCanvasElement | OffscreenCanvas$1> {
|
|
|
155
155
|
/** Dimensions to fit the renderer to. Will measure canvas dimensions if omitted */
|
|
156
156
|
size?: Size
|
|
157
157
|
/**
|
|
158
|
-
* Enables shadows (
|
|
159
|
-
* but also strings: 'basic' | 'percentage' | 'soft' | 'variance'.
|
|
158
|
+
* Enables shadows (`true` uses `THREE.PCFShadowMap`). Can accept `renderer.shadowMap` options for
|
|
159
|
+
* fine-tuning, but also strings: 'basic' | 'percentage' | 'soft' | 'variance'.
|
|
160
|
+
*
|
|
161
|
+
* `'soft'` is a deprecated alias of `'percentage'`: both map to `THREE.PCFShadowMap`, because three.js
|
|
162
|
+
* deprecated `PCFSoftShadowMap` and made `PCFShadowMap` soft. Using `'soft'` logs a deprecation notice.
|
|
160
163
|
* @see https://threejs.org/docs/#api/en/renderers/WebGLRenderer.shadowMap
|
|
161
164
|
*/
|
|
162
165
|
shadows?: boolean | 'basic' | 'percentage' | 'soft' | 'variance' | Partial<THREE.WebGLShadowMap>
|
|
@@ -540,8 +543,14 @@ type ThreeElement<T extends ConstructorRepresentation> = Mutable<
|
|
|
540
543
|
Overwrite<ElementProps<T>, Omit<InstanceProps<InstanceType<T>, T>, 'object'>>
|
|
541
544
|
>
|
|
542
545
|
|
|
546
|
+
/**
|
|
547
|
+
* Every constructor export of a three namespace as an uncapitalized JSX element. Non-constructor
|
|
548
|
+
* exports (constants, functions, nested namespaces) are dropped from the keys rather than mapped
|
|
549
|
+
* to `never`: a single `never`-valued key in `JSX.IntrinsicElements` collapses the props of any
|
|
550
|
+
* tag typed `React.ElementType` (#3898).
|
|
551
|
+
*/
|
|
543
552
|
type ThreeToJSXElements<T extends Record<string, any>> = {
|
|
544
|
-
[K in keyof T & string as
|
|
553
|
+
[K in keyof T & string as T[K] extends ConstructorRepresentation ? Uncapitalize<K> : never]: ThreeElement<T[K]>
|
|
545
554
|
}
|
|
546
555
|
|
|
547
556
|
/** Method names of Object3D, excluded from the `primitive` element's typed props. */
|
|
@@ -2246,16 +2255,67 @@ declare namespace ReactReconciler {
|
|
|
2246
2255
|
): void;
|
|
2247
2256
|
}
|
|
2248
2257
|
|
|
2258
|
+
/**
|
|
2259
|
+
* Registers constructors so they can be rendered as JSX elements.
|
|
2260
|
+
*
|
|
2261
|
+
* - `extend({ OrbitControls })` makes each constructor available under its camelCased key
|
|
2262
|
+
* (`<orbitControls />`). Values that are not constructors are skipped, so a whole module
|
|
2263
|
+
* namespace can be passed.
|
|
2264
|
+
* - `extend(MyClass)` registers one constructor and returns a component to render it with.
|
|
2265
|
+
*
|
|
2266
|
+
* Registrations are global, shared by every copy and entry of fiber, and are checked before the
|
|
2267
|
+
* three namespace of a root's renderer when an element name is resolved.
|
|
2268
|
+
*
|
|
2269
|
+
* @example
|
|
2270
|
+
* import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
|
|
2271
|
+
* extend({ OrbitControls })
|
|
2272
|
+
* // <orbitControls args={[camera, gl.domElement]} />
|
|
2273
|
+
*
|
|
2274
|
+
* @example
|
|
2275
|
+
* const Controls = extend(OrbitControls)
|
|
2276
|
+
* // <Controls args={[camera, gl.domElement]} />
|
|
2277
|
+
*
|
|
2278
|
+
* @see https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively
|
|
2279
|
+
*/
|
|
2249
2280
|
declare function extend<T extends ConstructorRepresentation>(objects: T): React$1.ExoticComponent<ThreeElement<T>>;
|
|
2281
|
+
/** Registers each constructor in `objects` under its key; see the first overload. */
|
|
2250
2282
|
declare function extend<T extends Catalogue>(objects: T): void;
|
|
2283
|
+
/** Registers every constructor in a module namespace, skipping other exports; see the first overload. */
|
|
2251
2284
|
declare function extend(objects: Record<string, unknown>): void;
|
|
2252
2285
|
|
|
2286
|
+
/**
|
|
2287
|
+
* R3F's React reconciler: a mutation-mode host config that turns JSX elements into three.js objects.
|
|
2288
|
+
* Each root's {@link RootStore} is its container, and children attach to `internal.container`
|
|
2289
|
+
* (a portal's target) or else the root's `scene`.
|
|
2290
|
+
*
|
|
2291
|
+
* - **Element names** resolve through `extend()` registrations first, then the three namespace of
|
|
2292
|
+
* the root's renderer. A `three` prefix (`<threeLine>`) is stripped when no element by the
|
|
2293
|
+
* prefixed name exists. `<primitive object={...}>` wraps an existing object.
|
|
2294
|
+
* - **Construction is deferred** until an instance is attached to a mounted parent, so a tree that
|
|
2295
|
+
* Suspense discards never creates three objects.
|
|
2296
|
+
* - **Updates** apply only changed props. Changing `args` (or a primitive's `object`) reconstructs
|
|
2297
|
+
* the object instead; the swap happens in `resetAfterCommit`, before layout effects, so refs
|
|
2298
|
+
* already point to the new object.
|
|
2299
|
+
* - **Removal** detaches the object and disposes it (at idle priority, or immediately in an `act`
|
|
2300
|
+
* test environment), unless it is a primitive, a `Scene`, or it or an ancestor has `dispose={null}`.
|
|
2301
|
+
* - **Priority**: not the primary renderer, so it runs alongside react-dom, and update priority
|
|
2302
|
+
* follows react-dom's event priorities. View-transition commits are flushed synchronously, since
|
|
2303
|
+
* three has nothing to animate between commits.
|
|
2304
|
+
*
|
|
2305
|
+
* `createRoot`, `createPortal` and `flushSync` drive it; app code rarely needs it directly.
|
|
2306
|
+
*/
|
|
2253
2307
|
declare const reconciler: ReactReconciler.Reconciler<RootStore, Instance<any>, void, Instance<any>, never, any>;
|
|
2254
2308
|
|
|
2255
2309
|
declare const isRenderer: (def: any) => boolean;
|
|
2256
2310
|
interface OffscreenCanvas extends EventTarget {
|
|
2257
2311
|
}
|
|
2258
2312
|
declare const _roots: Map<HTMLCanvasElement | OffscreenCanvas, Root>;
|
|
2313
|
+
/**
|
|
2314
|
+
* Unmount the root on `canvas`. The teardown runs once React has committed the unmount, and waits
|
|
2315
|
+
* for a renderer that is still being created. `callback` runs when the root is gone: after the
|
|
2316
|
+
* teardown, and when it disposed a renderer R3F created whose `dispose()` is async (WebGPURenderer
|
|
2317
|
+
* from three r186), after that dispose has settled.
|
|
2318
|
+
*/
|
|
2259
2319
|
declare function unmountComponentAtNode<TCanvas extends HTMLCanvasElement | OffscreenCanvas>(canvas: TCanvas, callback?: (canvas: TCanvas) => void): void;
|
|
2260
2320
|
declare function createPortal(children: ReactNode, container: THREE.Object3D | RefObject<THREE.Object3D | null> | RefObject<THREE.Object3D>, state?: InjectState): JSX.Element;
|
|
2261
2321
|
interface PortalProps {
|
|
@@ -2272,6 +2332,30 @@ declare function Portal({ children, container, state }: PortalProps): JSX.Elemen
|
|
|
2272
2332
|
*/
|
|
2273
2333
|
declare function flushSync<R>(fn: () => R): R;
|
|
2274
2334
|
|
|
2335
|
+
/**
|
|
2336
|
+
* Creates the Zustand store that holds one root's {@link RootState}.
|
|
2337
|
+
*
|
|
2338
|
+
* The store starts unconfigured: the renderer, `camera`, `scene`, `raycaster`, `frustum` and `pointer`
|
|
2339
|
+
* are `null` placeholders until the root's renderer support has loaded and `configure()` in
|
|
2340
|
+
* `renderer.tsx` fills them in. Only core's part of `RootState` is created here; packages building on
|
|
2341
|
+
* fiber add their own fields through root extensions.
|
|
2342
|
+
*
|
|
2343
|
+
* Besides the initial state, the store wires up:
|
|
2344
|
+
* - `state.gl` and `state.renderer` as accessors over `internal.actualRenderer`. `gl` reports a
|
|
2345
|
+
* deprecation when user code reads it outside legacy mode.
|
|
2346
|
+
* - `rootScene` following `scene` whenever `scene` is set to a real `THREE.Scene`.
|
|
2347
|
+
* - On a size or DPR change: updating the camera and resizing the root's own canvas target (or the
|
|
2348
|
+
* renderer when there is none).
|
|
2349
|
+
* - On a camera change: adding an unparented camera to `rootScene`, then refreshing the viewport and
|
|
2350
|
+
* (when `autoUpdateFrustum` is set) the frustum.
|
|
2351
|
+
* - Calling `invalidate(state)` after every state change.
|
|
2352
|
+
*
|
|
2353
|
+
* `createRoot` calls this once per canvas.
|
|
2354
|
+
*
|
|
2355
|
+
* @param invalidate - Requests frames for a root. Bound into `state.invalidate` and called on every store change.
|
|
2356
|
+
* @param advance - Steps a root manually. Bound into `state.advance`.
|
|
2357
|
+
* @returns The root's store, which is also the reconciler container for that root.
|
|
2358
|
+
*/
|
|
2275
2359
|
declare const createStore: (invalidate: (state?: RootState, frames?: number, stackFrames?: boolean) => void, advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState, frame?: XRFrame) => void) => RootStore;
|
|
2276
2360
|
|
|
2277
2361
|
/** Whether any root has loaded a renderer yet. */
|
|
@@ -361,4 +361,4 @@ function notifyRootExtensionsHmr(store) {
|
|
|
361
361
|
for (const setUpBy of applied.values()) current(registry, setUpBy).hmr?.(store);
|
|
362
362
|
}
|
|
363
363
|
|
|
364
|
-
export { Block as B, ErrorBoundary as E, useThree as a, useFrame as b, context as c, useIsomorphicLayoutEffect as d, useMutableCallback as e, useBridge as f, getTextureView as g, unstageTextures as h, stageTextures as i,
|
|
364
|
+
export { Block as B, ErrorBoundary as E, useThree as a, useFrame as b, context as c, useIsomorphicLayoutEffect as d, useMutableCallback as e, useBridge as f, getTextureView as g, unstageTextures as h, stageTextures as i, attachRootExtensions as j, detachRootExtensions as k, notifyAlpha as l, notifyRootExtensionsHmr as m, notifyDepreciated as n, registerRootExtension as r, setRenderOverride as s, useStore as u };
|
|
@@ -477,6 +477,11 @@ interface InternalState {
|
|
|
477
477
|
* Selected once, from the entry's provider, and copied into portals with the rest of `internal`.
|
|
478
478
|
*/
|
|
479
479
|
support: R3FRendererSupport
|
|
480
|
+
/**
|
|
481
|
+
* Releases this root's lease on its renderer. The last release disposes a renderer R3F created;
|
|
482
|
+
* a renderer passed in as an instance is never disposed by R3F.
|
|
483
|
+
*/
|
|
484
|
+
releaseRenderer?: () => void | Promise<void>
|
|
480
485
|
/** Global scheduler reference (for useFrame hook) */
|
|
481
486
|
scheduler: SchedulerApi | null
|
|
482
487
|
/**
|
|
@@ -489,6 +494,8 @@ interface InternalState {
|
|
|
489
494
|
rootId?: string
|
|
490
495
|
/** Function to unregister this root from the global scheduler */
|
|
491
496
|
unregisterRoot?: () => void
|
|
497
|
+
/** Function to stop following devicePixelRatio changes */
|
|
498
|
+
unwatchDpr?: () => void
|
|
492
499
|
/** Container for child attachment (scene for root, original container for portals) */
|
|
493
500
|
container?: THREE.Object3D
|
|
494
501
|
/**
|
|
@@ -660,9 +667,17 @@ type RootStore = UseBoundStoreWithEqualityFn<StoreApi<RootState>>
|
|
|
660
667
|
// to avoid bundling @types/react-reconciler which causes absolute path issues
|
|
661
668
|
type FiberRoot = any
|
|
662
669
|
|
|
670
|
+
/** A promise tagged with its state, the protocol React's `use` reads */
|
|
671
|
+
type TrackedPromise<T> = Promise<T> &
|
|
672
|
+
({ status: 'pending' } | { status: 'fulfilled'; value: T } | { status: 'rejected'; reason: unknown })
|
|
673
|
+
|
|
663
674
|
interface Root {
|
|
664
675
|
fiber: FiberRoot
|
|
665
676
|
store: RootStore
|
|
677
|
+
/** Set while a teardown waits on React. Configure and render clear it, which cancels the teardown */
|
|
678
|
+
unmountClaim: symbol | null
|
|
679
|
+
/** Pending only while a renderer is being created */
|
|
680
|
+
ready: TrackedPromise<unknown>
|
|
666
681
|
}
|
|
667
682
|
|
|
668
683
|
type AttachFnType<O = any> = (parent: any, self: O) => () => void
|
|
@@ -772,7 +787,14 @@ declare function useStore(): RootStore;
|
|
|
772
787
|
*/
|
|
773
788
|
declare function useThree<T = RootState>(selector?: (state: RootState) => T, equalityFn?: <T>(state: T, newState: T) => boolean): T;
|
|
774
789
|
|
|
790
|
+
/**
|
|
791
|
+
* React context that carries the current root's {@link RootStore}. Each root provides its store and
|
|
792
|
+
* each portal provides its own scoped one; `useStore`, and every hook built on it, reads it.
|
|
793
|
+
*
|
|
794
|
+
* Stored on `globalThis` under `Symbol.for('@react-three/fiber.context')`, so every copy and entry
|
|
795
|
+
* of fiber shares a single context.
|
|
796
|
+
*/
|
|
775
797
|
declare const context: React.Context<RootStore>;
|
|
776
798
|
|
|
777
|
-
export { useStore as
|
|
778
|
-
export type {
|
|
799
|
+
export { useStore as ah, useThree as ai, context as aj, registerRootExtension as r, setRenderOverride as s };
|
|
800
|
+
export type { ObjectMap as $, AttachFnType as A, ArgsProp as B, ConstructorRepresentation as C, Dpr as D, Events as E, Frameloop as F, InstanceProps as G, Instance as H, InternalState as I, HostConfig as J, Properties as K, IsOptional as L, Mutable as M, NonFunctionKeys as N, Overwrite as O, PointerState as P, IsAllOptional as Q, R3FRenderTarget as R, Subscription as S, ThreeEvent as T, ThreeCamera as U, Viewport as V, Act as W, XRManager as X, Bridge as Y, SetBlock as Z, UnblockProps as _, RootExtension as a, EquConfig as a0, Disposable as a1, FrameNextState as a2, FrameState as a3, FrameNextCallback as a4, FrameCallback as a5, ThreeNamespace as a6, ThreeCore as a7, OcclusionSupport as a8, WebGLSupport as a9, WebGPUSupport as aa, RendererSupport as ab, RendererProvider as ac, Register as ad, RegisteredRenderer as ae, ForRegisteredRenderer as af, R3FRendererSupport as ag, R3FRenderer as b, Size as c, RenderCallback as d, Performance as e, RootState as f, RootStore as g, Intersection as h, Camera as i, IntersectionEvent as j, DomEvent as k, EventHandlers as l, FilterFunction as m, ComputeFunction as n, XRPointerConfig as o, EventManager as p, PointerCaptureTarget as q, VisibilityEntry as t, FiberRoot as u, TrackedPromise as v, Root as w, AttachType as x, Catalogue as y, Args as z };
|