@react-three/fiber 10.0.0-alpha.1 → 10.0.0-canary.b0fafc8

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.
@@ -6,6 +6,12 @@ const jsxRuntime = require('react/jsx-runtime');
6
6
  const React = require('react');
7
7
  const useMeasure = require('react-use-measure');
8
8
  const itsFine = require('its-fine');
9
+ const fiber = require('@react-three/fiber');
10
+ const GroundedSkybox_js = require('three/examples/jsm/objects/GroundedSkybox.js');
11
+ const HDRLoader_js = require('three/examples/jsm/loaders/HDRLoader.js');
12
+ const EXRLoader_js = require('three/examples/jsm/loaders/EXRLoader.js');
13
+ const UltraHDRLoader_js = require('three/examples/jsm/loaders/UltraHDRLoader.js');
14
+ const gainmapJs = require('@monogrid/gainmap-js');
9
15
  const Tb = require('scheduler');
10
16
  const traditional = require('zustand/traditional');
11
17
  const suspendReact = require('suspend-react');
@@ -13,6 +19,7 @@ const lite = require('dequal/lite');
13
19
  require('zustand/shallow');
14
20
  const tsl = require('three/tsl');
15
21
 
22
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
16
23
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
17
24
 
18
25
  function _interopNamespaceCompat(e) {
@@ -66,9 +73,377 @@ const THREE = /*#__PURE__*/_mergeNamespaces({
66
73
  WebGLRenderer: WebGLRenderer
67
74
  }, [webgpu__namespace]);
68
75
 
69
- var __defProp$2 = Object.defineProperty;
70
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
71
- var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
76
+ const primaryRegistry = /* @__PURE__ */ new Map();
77
+ const pendingSubscribers = /* @__PURE__ */ new Map();
78
+ function registerPrimary(id, renderer, store) {
79
+ if (primaryRegistry.has(id)) {
80
+ console.warn(`Canvas with id="${id}" already registered. Overwriting.`);
81
+ }
82
+ const entry = { renderer, store };
83
+ primaryRegistry.set(id, entry);
84
+ const subscribers = pendingSubscribers.get(id);
85
+ if (subscribers) {
86
+ subscribers.forEach((callback) => callback(entry));
87
+ pendingSubscribers.delete(id);
88
+ }
89
+ return () => {
90
+ const currentEntry = primaryRegistry.get(id);
91
+ if (currentEntry?.renderer === renderer) {
92
+ primaryRegistry.delete(id);
93
+ }
94
+ };
95
+ }
96
+ function getPrimary(id) {
97
+ return primaryRegistry.get(id);
98
+ }
99
+ function waitForPrimary(id, timeout = 5e3) {
100
+ const existing = primaryRegistry.get(id);
101
+ if (existing) {
102
+ return Promise.resolve(existing);
103
+ }
104
+ return new Promise((resolve, reject) => {
105
+ const timeoutId = setTimeout(() => {
106
+ const subscribers = pendingSubscribers.get(id);
107
+ if (subscribers) {
108
+ const index = subscribers.indexOf(callback);
109
+ if (index !== -1) subscribers.splice(index, 1);
110
+ if (subscribers.length === 0) pendingSubscribers.delete(id);
111
+ }
112
+ reject(new Error(`Timeout waiting for canvas with id="${id}". Make sure a <Canvas id="${id}"> is mounted.`));
113
+ }, timeout);
114
+ const callback = (entry) => {
115
+ clearTimeout(timeoutId);
116
+ resolve(entry);
117
+ };
118
+ if (!pendingSubscribers.has(id)) {
119
+ pendingSubscribers.set(id, []);
120
+ }
121
+ pendingSubscribers.get(id).push(callback);
122
+ });
123
+ }
124
+ function hasPrimary(id) {
125
+ return primaryRegistry.has(id);
126
+ }
127
+ function unregisterPrimary(id) {
128
+ primaryRegistry.delete(id);
129
+ }
130
+ function getPrimaryIds() {
131
+ return Array.from(primaryRegistry.keys());
132
+ }
133
+
134
+ const presetsObj = {
135
+ apartment: "lebombo_1k.hdr",
136
+ city: "potsdamer_platz_1k.hdr",
137
+ dawn: "kiara_1_dawn_1k.hdr",
138
+ forest: "forest_slope_1k.hdr",
139
+ lobby: "st_fagans_interior_1k.hdr",
140
+ night: "dikhololo_night_1k.hdr",
141
+ park: "rooitou_park_1k.hdr",
142
+ studio: "studio_small_03_1k.hdr",
143
+ sunset: "venice_sunset_1k.hdr",
144
+ warehouse: "empty_warehouse_01_1k.hdr"
145
+ };
146
+
147
+ const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
148
+ const isArray = (arr) => Array.isArray(arr);
149
+ const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
150
+ function useEnvironment({
151
+ files = defaultFiles,
152
+ path = "",
153
+ preset = void 0,
154
+ colorSpace = void 0,
155
+ extensions
156
+ } = {}) {
157
+ if (preset) {
158
+ validatePreset(preset);
159
+ files = presetsObj[preset];
160
+ path = CUBEMAP_ROOT;
161
+ }
162
+ const multiFile = isArray(files);
163
+ const { extension, isCubemap } = getExtension(files);
164
+ const loader = getLoader$1(extension);
165
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
166
+ const renderer = fiber.useThree((state) => state.renderer);
167
+ React.useLayoutEffect(() => {
168
+ if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
169
+ function clearGainmapTexture() {
170
+ fiber.useLoader.clear(loader, multiFile ? [files] : files);
171
+ }
172
+ renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
173
+ }, [files, renderer.domElement]);
174
+ const loaderResult = fiber.useLoader(
175
+ loader,
176
+ multiFile ? [files] : files,
177
+ (loader2) => {
178
+ if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
179
+ loader2.setRenderer?.(renderer);
180
+ }
181
+ loader2.setPath?.(path);
182
+ if (extensions) extensions(loader2);
183
+ }
184
+ );
185
+ let texture = multiFile ? (
186
+ // @ts-ignore
187
+ loaderResult[0]
188
+ ) : loaderResult;
189
+ if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
190
+ texture = texture.renderTarget?.texture;
191
+ }
192
+ texture.mapping = isCubemap ? webgpu.CubeReflectionMapping : webgpu.EquirectangularReflectionMapping;
193
+ texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
194
+ return texture;
195
+ }
196
+ const preloadDefaultOptions = {
197
+ files: defaultFiles,
198
+ path: "",
199
+ preset: void 0,
200
+ extensions: void 0
201
+ };
202
+ useEnvironment.preload = (preloadOptions) => {
203
+ const options = { ...preloadDefaultOptions, ...preloadOptions };
204
+ let { files, path = "" } = options;
205
+ const { preset, extensions } = options;
206
+ if (preset) {
207
+ validatePreset(preset);
208
+ files = presetsObj[preset];
209
+ path = CUBEMAP_ROOT;
210
+ }
211
+ const { extension } = getExtension(files);
212
+ if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
213
+ throw new Error("useEnvironment: Preloading gainmaps is not supported");
214
+ }
215
+ const loader = getLoader$1(extension);
216
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
217
+ fiber.useLoader.preload(loader, isArray(files) ? [files] : files, (loader2) => {
218
+ loader2.setPath?.(path);
219
+ if (extensions) extensions(loader2);
220
+ });
221
+ };
222
+ const clearDefaultOptins = {
223
+ files: defaultFiles,
224
+ preset: void 0
225
+ };
226
+ useEnvironment.clear = (clearOptions) => {
227
+ const options = { ...clearDefaultOptins, ...clearOptions };
228
+ let { files } = options;
229
+ const { preset } = options;
230
+ if (preset) {
231
+ validatePreset(preset);
232
+ files = presetsObj[preset];
233
+ }
234
+ const { extension } = getExtension(files);
235
+ const loader = getLoader$1(extension);
236
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
237
+ fiber.useLoader.clear(loader, isArray(files) ? [files] : files);
238
+ };
239
+ function validatePreset(preset) {
240
+ if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
241
+ }
242
+ function getExtension(files) {
243
+ const isCubemap = isArray(files) && files.length === 6;
244
+ const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
245
+ const firstEntry = isArray(files) ? files[0] : files;
246
+ const extension = isCubemap ? "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
247
+ return { extension, isCubemap, isGainmap };
248
+ }
249
+ function getLoader$1(extension) {
250
+ const loader = extension === "cube" ? webgpu.CubeTextureLoader : extension === "hdr" ? HDRLoader_js.HDRLoader : extension === "exr" ? EXRLoader_js.EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader_js.UltraHDRLoader : extension === "webp" ? gainmapJs.GainMapLoader : null;
251
+ return loader;
252
+ }
253
+
254
+ const isRef$1 = (obj) => obj.current && obj.current.isScene;
255
+ const resolveScene = (scene) => isRef$1(scene) ? scene.current : scene;
256
+ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
257
+ sceneProps = {
258
+ backgroundBlurriness: 0,
259
+ backgroundIntensity: 1,
260
+ backgroundRotation: [0, 0, 0],
261
+ environmentIntensity: 1,
262
+ environmentRotation: [0, 0, 0],
263
+ ...sceneProps
264
+ };
265
+ const target = resolveScene(scene || defaultScene);
266
+ const oldbg = target.background;
267
+ const oldenv = target.environment;
268
+ const oldSceneProps = {
269
+ // @ts-ignore
270
+ backgroundBlurriness: target.backgroundBlurriness,
271
+ // @ts-ignore
272
+ backgroundIntensity: target.backgroundIntensity,
273
+ // @ts-ignore
274
+ backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
275
+ // @ts-ignore
276
+ environmentIntensity: target.environmentIntensity,
277
+ // @ts-ignore
278
+ environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
279
+ };
280
+ if (background !== "only") target.environment = texture;
281
+ if (background) target.background = texture;
282
+ fiber.applyProps(target, sceneProps);
283
+ return () => {
284
+ if (background !== "only") target.environment = oldenv;
285
+ if (background) target.background = oldbg;
286
+ fiber.applyProps(target, oldSceneProps);
287
+ };
288
+ }
289
+ function EnvironmentMap({ scene, background = false, map, ...config }) {
290
+ const defaultScene = fiber.useThree((state) => state.scene);
291
+ React__namespace.useLayoutEffect(() => {
292
+ if (map) return setEnvProps(background, scene, defaultScene, map, config);
293
+ });
294
+ return null;
295
+ }
296
+ function EnvironmentCube({
297
+ background = false,
298
+ scene,
299
+ blur,
300
+ backgroundBlurriness,
301
+ backgroundIntensity,
302
+ backgroundRotation,
303
+ environmentIntensity,
304
+ environmentRotation,
305
+ ...rest
306
+ }) {
307
+ const texture = useEnvironment(rest);
308
+ const defaultScene = fiber.useThree((state) => state.scene);
309
+ React__namespace.useLayoutEffect(() => {
310
+ return setEnvProps(background, scene, defaultScene, texture, {
311
+ backgroundBlurriness: blur ?? backgroundBlurriness,
312
+ backgroundIntensity,
313
+ backgroundRotation,
314
+ environmentIntensity,
315
+ environmentRotation
316
+ });
317
+ });
318
+ React__namespace.useEffect(() => {
319
+ return () => {
320
+ texture.dispose();
321
+ };
322
+ }, [texture]);
323
+ return null;
324
+ }
325
+ function EnvironmentPortal({
326
+ children,
327
+ near = 0.1,
328
+ far = 1e3,
329
+ resolution = 256,
330
+ frames = 1,
331
+ map,
332
+ background = false,
333
+ blur,
334
+ backgroundBlurriness,
335
+ backgroundIntensity,
336
+ backgroundRotation,
337
+ environmentIntensity,
338
+ environmentRotation,
339
+ scene,
340
+ files,
341
+ path,
342
+ preset = void 0,
343
+ extensions
344
+ }) {
345
+ const gl = fiber.useThree((state) => state.gl);
346
+ const defaultScene = fiber.useThree((state) => state.scene);
347
+ const camera = React__namespace.useRef(null);
348
+ const [virtualScene] = React__namespace.useState(() => new webgpu.Scene());
349
+ const fbo = React__namespace.useMemo(() => {
350
+ const fbo2 = new webgpu.WebGLCubeRenderTarget(resolution);
351
+ fbo2.texture.type = webgpu.HalfFloatType;
352
+ return fbo2;
353
+ }, [resolution]);
354
+ React__namespace.useEffect(() => {
355
+ return () => {
356
+ fbo.dispose();
357
+ };
358
+ }, [fbo]);
359
+ React__namespace.useLayoutEffect(() => {
360
+ if (frames === 1) {
361
+ const autoClear = gl.autoClear;
362
+ gl.autoClear = true;
363
+ camera.current.update(gl, virtualScene);
364
+ gl.autoClear = autoClear;
365
+ }
366
+ return setEnvProps(background, scene, defaultScene, fbo.texture, {
367
+ backgroundBlurriness: blur ?? backgroundBlurriness,
368
+ backgroundIntensity,
369
+ backgroundRotation,
370
+ environmentIntensity,
371
+ environmentRotation
372
+ });
373
+ }, [children, virtualScene, fbo.texture, scene, defaultScene, background, frames, gl]);
374
+ let count = 1;
375
+ fiber.useFrame(() => {
376
+ if (frames === Infinity || count < frames) {
377
+ const autoClear = gl.autoClear;
378
+ gl.autoClear = true;
379
+ camera.current.update(gl, virtualScene);
380
+ gl.autoClear = autoClear;
381
+ count++;
382
+ }
383
+ });
384
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fiber.createPortal(
385
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
386
+ children,
387
+ /* @__PURE__ */ jsxRuntime.jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
388
+ files || preset ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { background: true, map, extensions }) : null
389
+ ] }),
390
+ virtualScene
391
+ ) });
392
+ }
393
+ function EnvironmentGround(props) {
394
+ const textureDefault = useEnvironment(props);
395
+ const texture = props.map || textureDefault;
396
+ React__namespace.useMemo(() => fiber.extend({ GroundProjectedEnvImpl: GroundedSkybox_js.GroundedSkybox }), []);
397
+ React__namespace.useEffect(() => {
398
+ return () => {
399
+ textureDefault.dispose();
400
+ };
401
+ }, [textureDefault]);
402
+ const height = props.ground?.height ?? 15;
403
+ const radius = props.ground?.radius ?? 60;
404
+ const scale = props.ground?.scale ?? 1e3;
405
+ const args = React__namespace.useMemo(
406
+ () => [texture, height, radius],
407
+ [texture, height, radius]
408
+ );
409
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
410
+ /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props, map: texture }),
411
+ /* @__PURE__ */ jsxRuntime.jsx("groundProjectedEnvImpl", { args, scale })
412
+ ] });
413
+ }
414
+ function EnvironmentColor({ color, scene }) {
415
+ const defaultScene = fiber.useThree((state) => state.scene);
416
+ React__namespace.useLayoutEffect(() => {
417
+ if (color === void 0) return;
418
+ const target = resolveScene(scene || defaultScene);
419
+ const oldBg = target.background;
420
+ target.background = new webgpu.Color(color);
421
+ return () => {
422
+ target.background = oldBg;
423
+ };
424
+ });
425
+ return null;
426
+ }
427
+ function EnvironmentDualSource(props) {
428
+ const { backgroundFiles, ...envProps } = props;
429
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
430
+ /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...envProps, background: false }),
431
+ /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
432
+ ] });
433
+ }
434
+ function Environment(props) {
435
+ if (props.color && !props.files && !props.preset && !props.map) {
436
+ return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentColor, { ...props });
437
+ }
438
+ if (props.backgroundFiles && props.backgroundFiles !== props.files) {
439
+ return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentDualSource, { ...props });
440
+ }
441
+ return props.ground ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentGround, { ...props }) : props.map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props }) : props.children ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentPortal, { ...props }) : /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props });
442
+ }
443
+
444
+ var __defProp$3 = Object.defineProperty;
445
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
446
+ var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
72
447
  const act = React__namespace["act"];
73
448
  const useIsomorphicLayoutEffect = /* @__PURE__ */ (() => typeof window !== "undefined" && (window.document?.createElement || window.navigator?.product === "ReactNative"))() ? React__namespace.useLayoutEffect : React__namespace.useEffect;
74
449
  function useMutableCallback(fn) {
@@ -100,7 +475,7 @@ const ErrorBoundary = /* @__PURE__ */ (() => {
100
475
  return _a = class extends React__namespace.Component {
101
476
  constructor() {
102
477
  super(...arguments);
103
- __publicField$2(this, "state", { error: false });
478
+ __publicField$3(this, "state", { error: false });
104
479
  }
105
480
  componentDidCatch(err) {
106
481
  this.props.set(err);
@@ -108,7 +483,7 @@ const ErrorBoundary = /* @__PURE__ */ (() => {
108
483
  render() {
109
484
  return this.state.error ? null : this.props.children;
110
485
  }
111
- }, __publicField$2(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
486
+ }, __publicField$3(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
112
487
  })();
113
488
 
114
489
  const is = {
@@ -245,7 +620,8 @@ function prepare(target, root, type, props) {
245
620
  object,
246
621
  eventCount: 0,
247
622
  handlers: {},
248
- isHidden: false
623
+ isHidden: false,
624
+ deferredRefs: []
249
625
  };
250
626
  if (object) object.__r3f = instance;
251
627
  }
@@ -294,7 +670,7 @@ function createOcclusionObserverNode(store, uniform) {
294
670
  let occlusionSetupPromise = null;
295
671
  function enableOcclusion(store) {
296
672
  const state = store.getState();
297
- const { internal, renderer, rootScene } = state;
673
+ const { internal, renderer } = state;
298
674
  if (internal.occlusionEnabled || occlusionSetupPromise) return;
299
675
  const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
300
676
  if (!hasOcclusionSupport) {
@@ -457,6 +833,22 @@ function hasVisibilityHandlers(handlers) {
457
833
  return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
458
834
  }
459
835
 
836
+ const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
837
+ function fromRef(ref) {
838
+ return { [FROM_REF]: ref };
839
+ }
840
+ function isFromRef(value) {
841
+ return value !== null && typeof value === "object" && FROM_REF in value;
842
+ }
843
+
844
+ const ONCE = Symbol.for("@react-three/fiber.once");
845
+ function once(...args) {
846
+ return { [ONCE]: args.length ? args : true };
847
+ }
848
+ function isOnce(value) {
849
+ return value !== null && typeof value === "object" && ONCE in value;
850
+ }
851
+
460
852
  const RESERVED_PROPS = [
461
853
  "children",
462
854
  "key",
@@ -527,7 +919,7 @@ function getMemoizedPrototype(root) {
527
919
  ctor = new root.constructor();
528
920
  MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
529
921
  }
530
- } catch (e) {
922
+ } catch {
531
923
  }
532
924
  return ctor;
533
925
  }
@@ -558,7 +950,7 @@ function applyProps(object, props) {
558
950
  const rootState = instance && findInitialRoot(instance).getState();
559
951
  const prevHandlers = instance?.eventCount;
560
952
  for (const prop in props) {
561
- let value = props[prop];
953
+ const value = props[prop];
562
954
  if (RESERVED_PROPS.includes(prop)) continue;
563
955
  if (instance && EVENT_REGEX.test(prop)) {
564
956
  if (typeof value === "function") instance.handlers[prop] = value;
@@ -573,6 +965,25 @@ function applyProps(object, props) {
573
965
  continue;
574
966
  }
575
967
  if (value === void 0) continue;
968
+ if (isFromRef(value)) {
969
+ instance?.deferredRefs?.push({ prop, ref: value[FROM_REF] });
970
+ continue;
971
+ }
972
+ if (isOnce(value)) {
973
+ if (instance?.appliedOnce?.has(prop)) continue;
974
+ if (instance) {
975
+ instance.appliedOnce ?? (instance.appliedOnce = /* @__PURE__ */ new Set());
976
+ instance.appliedOnce.add(prop);
977
+ }
978
+ const { root: targetRoot, key: targetKey } = resolve(object, prop);
979
+ const args = value[ONCE];
980
+ if (typeof targetRoot[targetKey] === "function") {
981
+ targetRoot[targetKey](...args === true ? [] : args);
982
+ } else if (args !== true && args.length > 0) {
983
+ targetRoot[targetKey] = args[0];
984
+ }
985
+ continue;
986
+ }
576
987
  let { root, key, target } = resolve(object, prop);
577
988
  if (target === void 0 && (typeof root !== "object" || root === null)) {
578
989
  throw Error(`R3F: Cannot set "${prop}". Ensure it is an object before setting "${key}".`);
@@ -595,7 +1006,7 @@ function applyProps(object, props) {
595
1006
  else target.set(value);
596
1007
  } else {
597
1008
  root[key] = value;
598
- if (rootState && !rootState.linear && colorMaps.includes(key) && isTexture(value) && root[key]?.isTexture && // sRGB textures must be RGBA8 since r137 https://github.com/mrdoob/three.js/pull/23129
1009
+ if (rootState && rootState.renderer?.outputColorSpace === webgpu.SRGBColorSpace && colorMaps.includes(key) && isTexture(value) && root[key]?.isTexture && // sRGB textures must be RGBA8 since r137 https://github.com/mrdoob/three.js/pull/23129
599
1010
  root[key].format === webgpu.RGBAFormat && root[key].type === webgpu.UnsignedByteType) {
600
1011
  root[key].colorSpace = rootState.textureColorSpace;
601
1012
  }
@@ -710,13 +1121,14 @@ function createEvents(store) {
710
1121
  for (const hit of hits) {
711
1122
  let eventObject = hit.object;
712
1123
  while (eventObject) {
713
- if (eventObject.__r3f?.eventCount)
1124
+ if (eventObject.__r3f?.eventCount) {
714
1125
  intersections.push({ ...hit, eventObject });
1126
+ }
715
1127
  eventObject = eventObject.parent;
716
1128
  }
717
1129
  }
718
1130
  if ("pointerId" in event && state.internal.capturedMap.has(event.pointerId)) {
719
- for (let captureData of state.internal.capturedMap.get(event.pointerId).values()) {
1131
+ for (const captureData of state.internal.capturedMap.get(event.pointerId).values()) {
720
1132
  if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
721
1133
  }
722
1134
  }
@@ -746,12 +1158,12 @@ function createEvents(store) {
746
1158
  releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
747
1159
  }
748
1160
  };
749
- let extractEventProps = {};
750
- for (let prop in event) {
751
- let property = event[prop];
1161
+ const extractEventProps = {};
1162
+ for (const prop in event) {
1163
+ const property = event[prop];
752
1164
  if (typeof property !== "function") extractEventProps[prop] = property;
753
1165
  }
754
- let raycastEvent = {
1166
+ const raycastEvent = {
755
1167
  ...hit,
756
1168
  ...extractEventProps,
757
1169
  pointer,
@@ -951,7 +1363,7 @@ function createPointerEvents(store) {
951
1363
  return {
952
1364
  priority: 1,
953
1365
  enabled: true,
954
- compute(event, state, previous) {
1366
+ compute(event, state) {
955
1367
  state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
956
1368
  state.raycaster.setFromCamera(state.pointer, state.camera);
957
1369
  },
@@ -1010,331 +1422,57 @@ function notifyDepreciated({ heading, body, link }) {
1010
1422
  if (body || link) {
1011
1423
  let message = "";
1012
1424
  if (body) message += body;
1013
- if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
1014
- console.warn(`%c${message}`, "font-weight: bold;");
1015
- }
1016
- }
1017
- function getCallerFrame(depth = 3) {
1018
- const stack = new Error().stack;
1019
- if (!stack) return null;
1020
- const lines = stack.split("\n");
1021
- const frame = lines[depth];
1022
- if (!frame) return null;
1023
- let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
1024
- if (!match) {
1025
- match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
1026
- }
1027
- if (!match) return null;
1028
- const [, fn, url, line] = match;
1029
- return {
1030
- functionName: fn ?? "<anonymous>",
1031
- location: formatLocation(url, Number(line))
1032
- };
1033
- }
1034
- function formatLocation(url, line) {
1035
- const clean = url.split("?")[0];
1036
- const file = clean.split("/").pop() ?? clean;
1037
- return `${file}:${line}`;
1038
- }
1039
- function notifyAlpha({ message, link }) {
1040
- if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
1041
- return;
1042
- }
1043
- if (shownNotices.has(message)) return;
1044
- shownNotices.add(message);
1045
- const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
1046
- console.log(`%c\u{1F52C} ${message}`, boxStyle);
1047
- {
1048
- console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
1049
- }
1050
- }
1051
-
1052
- const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
1053
- const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React__namespace.createContext(null));
1054
- const createStore = (invalidate, advance) => {
1055
- const rootStore = traditional.createWithEqualityFn((set, get) => {
1056
- const position = new webgpu.Vector3();
1057
- const defaultTarget = new webgpu.Vector3();
1058
- const tempTarget = new webgpu.Vector3();
1059
- function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
1060
- const { width, height, top, left } = size;
1061
- const aspect = width / height;
1062
- if (target.isVector3) tempTarget.copy(target);
1063
- else tempTarget.set(...target);
1064
- const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
1065
- if (isOrthographicCamera(camera)) {
1066
- return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
1067
- } else {
1068
- const fov = camera.fov * Math.PI / 180;
1069
- const h = 2 * Math.tan(fov / 2) * distance;
1070
- const w = h * (width / height);
1071
- return { width: w, height: h, top, left, factor: width / w, distance, aspect };
1072
- }
1073
- }
1074
- let performanceTimeout = void 0;
1075
- const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
1076
- const pointer = new webgpu.Vector2();
1077
- const rootState = {
1078
- set,
1079
- get,
1080
- // Mock objects that have to be configured
1081
- gl: null,
1082
- renderer: null,
1083
- camera: null,
1084
- frustum: new webgpu.Frustum(),
1085
- autoUpdateFrustum: true,
1086
- raycaster: null,
1087
- events: { priority: 1, enabled: true, connected: false },
1088
- scene: null,
1089
- rootScene: null,
1090
- xr: null,
1091
- inspector: null,
1092
- invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
1093
- advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
1094
- legacy: false,
1095
- linear: false,
1096
- flat: false,
1097
- textureColorSpace: "srgb",
1098
- isLegacy: false,
1099
- webGPUSupported: false,
1100
- isNative: false,
1101
- controls: null,
1102
- pointer,
1103
- mouse: pointer,
1104
- frameloop: "always",
1105
- onPointerMissed: void 0,
1106
- onDragOverMissed: void 0,
1107
- onDropMissed: void 0,
1108
- performance: {
1109
- current: 1,
1110
- min: 0.5,
1111
- max: 1,
1112
- debounce: 200,
1113
- regress: () => {
1114
- const state2 = get();
1115
- if (performanceTimeout) clearTimeout(performanceTimeout);
1116
- if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
1117
- performanceTimeout = setTimeout(
1118
- () => setPerformanceCurrent(get().performance.max),
1119
- state2.performance.debounce
1120
- );
1121
- }
1122
- },
1123
- size: { width: 0, height: 0, top: 0, left: 0 },
1124
- viewport: {
1125
- initialDpr: 0,
1126
- dpr: 0,
1127
- width: 0,
1128
- height: 0,
1129
- top: 0,
1130
- left: 0,
1131
- aspect: 0,
1132
- distance: 0,
1133
- factor: 0,
1134
- getCurrentViewport
1135
- },
1136
- setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
1137
- setSize: (width, height, top = 0, left = 0) => {
1138
- const camera = get().camera;
1139
- const size = { width, height, top, left };
1140
- set((state2) => ({ size, viewport: { ...state2.viewport, ...getCurrentViewport(camera, defaultTarget, size) } }));
1141
- },
1142
- setDpr: (dpr) => set((state2) => {
1143
- const resolved = calculateDpr(dpr);
1144
- return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
1145
- }),
1146
- setFrameloop: (frameloop = "always") => {
1147
- set(() => ({ frameloop }));
1148
- },
1149
- setError: (error) => set(() => ({ error })),
1150
- error: null,
1151
- //* TSL State (managed via hooks: useUniforms, useNodes, useTextures, usePostProcessing) ==============================
1152
- uniforms: {},
1153
- nodes: {},
1154
- textures: /* @__PURE__ */ new Map(),
1155
- postProcessing: null,
1156
- passes: {},
1157
- previousRoot: void 0,
1158
- internal: {
1159
- // Events
1160
- interaction: [],
1161
- hovered: /* @__PURE__ */ new Map(),
1162
- subscribers: [],
1163
- initialClick: [0, 0],
1164
- initialHits: [],
1165
- capturedMap: /* @__PURE__ */ new Map(),
1166
- lastEvent: React__namespace.createRef(),
1167
- // Visibility tracking (onFramed, onOccluded, onVisible)
1168
- visibilityRegistry: /* @__PURE__ */ new Map(),
1169
- // Occlusion system (WebGPU only)
1170
- occlusionEnabled: false,
1171
- occlusionObserver: null,
1172
- occlusionCache: /* @__PURE__ */ new Map(),
1173
- helperGroup: null,
1174
- // Updates
1175
- active: false,
1176
- frames: 0,
1177
- priority: 0,
1178
- subscribe: (ref, priority, store) => {
1179
- const internal = get().internal;
1180
- internal.priority = internal.priority + (priority > 0 ? 1 : 0);
1181
- internal.subscribers.push({ ref, priority, store });
1182
- internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
1183
- return () => {
1184
- const internal2 = get().internal;
1185
- if (internal2?.subscribers) {
1186
- internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
1187
- internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
1188
- }
1189
- };
1190
- },
1191
- // Renderer Storage (single source of truth)
1192
- actualRenderer: null,
1193
- // Scheduler for useFrameNext (initialized in renderer.tsx)
1194
- scheduler: null
1195
- }
1196
- };
1197
- return rootState;
1198
- });
1199
- const state = rootStore.getState();
1200
- Object.defineProperty(state, "gl", {
1201
- get() {
1202
- const currentState = rootStore.getState();
1203
- if (!currentState.isLegacy && currentState.internal.actualRenderer) {
1204
- const stack = new Error().stack || "";
1205
- const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
1206
- if (!isInternalAccess) {
1207
- const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
1208
- notifyDepreciated({
1209
- heading: "Accessing state.gl in WebGPU mode",
1210
- body: "Please use state.renderer instead. state.gl is deprecated and will be removed in future versions.\n\nFor backwards compatibility, state.gl currently maps to state.renderer, but this may cause issues with libraries expecting WebGLRenderer.\n\nAccessed from:\n" + cleanedStack
1211
- });
1212
- }
1213
- }
1214
- return currentState.internal.actualRenderer;
1215
- },
1216
- set(value) {
1217
- rootStore.getState().internal.actualRenderer = value;
1218
- },
1219
- enumerable: true,
1220
- configurable: true
1221
- });
1222
- Object.defineProperty(state, "renderer", {
1223
- get() {
1224
- return rootStore.getState().internal.actualRenderer;
1225
- },
1226
- set(value) {
1227
- rootStore.getState().internal.actualRenderer = value;
1228
- },
1229
- enumerable: true,
1230
- configurable: true
1231
- });
1232
- let oldScene = state.scene;
1233
- rootStore.subscribe(() => {
1234
- const currentState = rootStore.getState();
1235
- const { scene, rootScene, set } = currentState;
1236
- if (scene !== oldScene) {
1237
- oldScene = scene;
1238
- if (scene?.isScene && scene !== rootScene) {
1239
- set({ rootScene: scene });
1240
- }
1241
- }
1242
- });
1243
- let oldSize = state.size;
1244
- let oldDpr = state.viewport.dpr;
1245
- let oldCamera = state.camera;
1246
- rootStore.subscribe(() => {
1247
- const { camera, size, viewport, set, internal } = rootStore.getState();
1248
- const actualRenderer = internal.actualRenderer;
1249
- if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
1250
- oldSize = size;
1251
- oldDpr = viewport.dpr;
1252
- updateCamera(camera, size);
1253
- if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
1254
- const updateStyle = typeof HTMLCanvasElement !== "undefined" && actualRenderer.domElement instanceof HTMLCanvasElement;
1255
- actualRenderer.setSize(size.width, size.height, updateStyle);
1256
- }
1257
- if (camera !== oldCamera) {
1258
- oldCamera = camera;
1259
- const { rootScene } = rootStore.getState();
1260
- if (camera && rootScene && !camera.parent) {
1261
- rootScene.add(camera);
1262
- }
1263
- set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
1264
- const currentState = rootStore.getState();
1265
- if (currentState.autoUpdateFrustum && camera) {
1266
- updateFrustum(camera, currentState.frustum);
1267
- }
1268
- }
1269
- });
1270
- rootStore.subscribe((state2) => invalidate(state2));
1271
- return rootStore;
1272
- };
1273
-
1274
- const memoizedLoaders = /* @__PURE__ */ new WeakMap();
1275
- const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
1276
- function getLoader(Proto) {
1277
- if (isConstructor$1(Proto)) {
1278
- let loader = memoizedLoaders.get(Proto);
1279
- if (!loader) {
1280
- loader = new Proto();
1281
- memoizedLoaders.set(Proto, loader);
1282
- }
1283
- return loader;
1284
- }
1285
- return Proto;
1286
- }
1287
- function loadingFn(extensions, onProgress) {
1288
- return function(Proto, input) {
1289
- const loader = getLoader(Proto);
1290
- if (extensions) extensions(loader);
1291
- if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
1292
- return loader.loadAsync(input, onProgress).then((data) => {
1293
- if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
1294
- return data;
1295
- });
1296
- }
1297
- return new Promise(
1298
- (res, reject) => loader.load(
1299
- input,
1300
- (data) => {
1301
- if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
1302
- res(data);
1303
- },
1304
- onProgress,
1305
- (error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
1306
- )
1307
- );
1425
+ if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
1426
+ console.warn(`%c${message}`, "font-weight: bold;");
1427
+ }
1428
+ }
1429
+ function getCallerFrame(depth = 3) {
1430
+ const stack = new Error().stack;
1431
+ if (!stack) return null;
1432
+ const lines = stack.split("\n");
1433
+ const frame = lines[depth];
1434
+ if (!frame) return null;
1435
+ let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
1436
+ if (!match) {
1437
+ match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
1438
+ }
1439
+ if (!match) return null;
1440
+ const [, fn, url, line] = match;
1441
+ return {
1442
+ functionName: fn ?? "<anonymous>",
1443
+ location: formatLocation(url, Number(line))
1308
1444
  };
1309
1445
  }
1310
- function useLoader(loader, input, extensions, onProgress) {
1311
- const keys = Array.isArray(input) ? input : [input];
1312
- const fn = loadingFn(extensions, onProgress);
1313
- const results = keys.map((key) => suspendReact.suspend(fn, [loader, key], { equal: is.equ }));
1314
- return Array.isArray(input) ? results : results[0];
1446
+ function formatLocation(url, line) {
1447
+ const clean = url.split("?")[0];
1448
+ const file = clean.split("/").pop() ?? clean;
1449
+ return `${file}:${line}`;
1450
+ }
1451
+ function notifyAlpha({ message, link }) {
1452
+ if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
1453
+ return;
1454
+ }
1455
+ if (shownNotices.has(message)) return;
1456
+ shownNotices.add(message);
1457
+ const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
1458
+ console.log(`%c\u{1F52C} ${message}`, boxStyle);
1459
+ {
1460
+ console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
1461
+ }
1315
1462
  }
1316
- useLoader.preload = function(loader, input, extensions, onProgress) {
1317
- const keys = Array.isArray(input) ? input : [input];
1318
- keys.forEach((key) => suspendReact.preload(loadingFn(extensions, onProgress), [loader, key]));
1319
- };
1320
- useLoader.clear = function(loader, input) {
1321
- const keys = Array.isArray(input) ? input : [input];
1322
- keys.forEach((key) => suspendReact.clear([loader, key]));
1323
- };
1324
- useLoader.loader = getLoader;
1325
1463
 
1326
- var __defProp$1 = Object.defineProperty;
1327
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1328
- var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
1464
+ var __defProp$2 = Object.defineProperty;
1465
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1466
+ var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
1329
1467
  const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
1330
1468
  class PhaseGraph {
1331
1469
  constructor() {
1332
1470
  /** Ordered list of phase nodes */
1333
- __publicField$1(this, "phases", []);
1471
+ __publicField$2(this, "phases", []);
1334
1472
  /** Quick lookup by name */
1335
- __publicField$1(this, "phaseMap", /* @__PURE__ */ new Map());
1473
+ __publicField$2(this, "phaseMap", /* @__PURE__ */ new Map());
1336
1474
  /** Cached ordered names (invalidated on changes) */
1337
- __publicField$1(this, "orderedNamesCache", null);
1475
+ __publicField$2(this, "orderedNamesCache", null);
1338
1476
  this.initializeDefaultPhases();
1339
1477
  }
1340
1478
  //* Initialization --------------------------------
@@ -1361,8 +1499,9 @@ class PhaseGraph {
1361
1499
  const node = { name, isAutoGenerated: false };
1362
1500
  let insertIndex = this.phases.length;
1363
1501
  const targetIndex = this.getPhaseIndex(before ?? after);
1364
- if (targetIndex !== -1) insertIndex = before ? targetIndex : targetIndex + 1;
1365
- else {
1502
+ if (targetIndex !== -1) {
1503
+ insertIndex = before ? targetIndex : targetIndex + 1;
1504
+ } else {
1366
1505
  const constraintType = before ? "before" : "after";
1367
1506
  console.warn(`[useFrame] Phase "${before ?? after}" not found for '${constraintType}' constraint`);
1368
1507
  }
@@ -1590,9 +1729,9 @@ function resetJobTiming(job) {
1590
1729
  job.lastRun = void 0;
1591
1730
  }
1592
1731
 
1593
- var __defProp = Object.defineProperty;
1594
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1595
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1732
+ var __defProp$1 = Object.defineProperty;
1733
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1734
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
1596
1735
  const hmrData = (() => {
1597
1736
  if (typeof process !== "undefined" && process.env.NODE_ENV === "test") return void 0;
1598
1737
  if (typeof import_meta_hot !== "undefined") return import_meta_hot;
@@ -1606,9 +1745,9 @@ const _Scheduler = class _Scheduler {
1606
1745
  //* Constructor ================================
1607
1746
  constructor() {
1608
1747
  //* Critical State ================================
1609
- __publicField(this, "roots", /* @__PURE__ */ new Map());
1610
- __publicField(this, "phaseGraph");
1611
- __publicField(this, "loopState", {
1748
+ __publicField$1(this, "roots", /* @__PURE__ */ new Map());
1749
+ __publicField$1(this, "phaseGraph");
1750
+ __publicField$1(this, "loopState", {
1612
1751
  running: false,
1613
1752
  rafHandle: null,
1614
1753
  lastTime: null,
@@ -1617,21 +1756,21 @@ const _Scheduler = class _Scheduler {
1617
1756
  elapsedTime: 0,
1618
1757
  createdAt: performance.now()
1619
1758
  });
1620
- __publicField(this, "stoppedTime", 0);
1759
+ __publicField$1(this, "stoppedTime", 0);
1621
1760
  //* Private State ================================
1622
- __publicField(this, "nextRootIndex", 0);
1623
- __publicField(this, "globalBeforeJobs", /* @__PURE__ */ new Map());
1624
- __publicField(this, "globalAfterJobs", /* @__PURE__ */ new Map());
1625
- __publicField(this, "nextGlobalIndex", 0);
1626
- __publicField(this, "idleCallbacks", /* @__PURE__ */ new Set());
1627
- __publicField(this, "nextJobIndex", 0);
1628
- __publicField(this, "jobStateListeners", /* @__PURE__ */ new Map());
1629
- __publicField(this, "pendingFrames", 0);
1630
- __publicField(this, "_frameloop", "always");
1761
+ __publicField$1(this, "nextRootIndex", 0);
1762
+ __publicField$1(this, "globalBeforeJobs", /* @__PURE__ */ new Map());
1763
+ __publicField$1(this, "globalAfterJobs", /* @__PURE__ */ new Map());
1764
+ __publicField$1(this, "nextGlobalIndex", 0);
1765
+ __publicField$1(this, "idleCallbacks", /* @__PURE__ */ new Set());
1766
+ __publicField$1(this, "nextJobIndex", 0);
1767
+ __publicField$1(this, "jobStateListeners", /* @__PURE__ */ new Map());
1768
+ __publicField$1(this, "pendingFrames", 0);
1769
+ __publicField$1(this, "_frameloop", "always");
1631
1770
  //* Independent Mode & Error Handling State ================================
1632
- __publicField(this, "_independent", false);
1633
- __publicField(this, "errorHandler", null);
1634
- __publicField(this, "rootReadyCallbacks", /* @__PURE__ */ new Set());
1771
+ __publicField$1(this, "_independent", false);
1772
+ __publicField$1(this, "errorHandler", null);
1773
+ __publicField$1(this, "rootReadyCallbacks", /* @__PURE__ */ new Set());
1635
1774
  //* Core Loop Execution Methods ================================
1636
1775
  /**
1637
1776
  * Main RAF loop callback.
@@ -1640,7 +1779,7 @@ const _Scheduler = class _Scheduler {
1640
1779
  * @returns {void}
1641
1780
  * @private
1642
1781
  */
1643
- __publicField(this, "loop", (timestamp) => {
1782
+ __publicField$1(this, "loop", (timestamp) => {
1644
1783
  if (!this.loopState.running) return;
1645
1784
  this.executeFrame(timestamp);
1646
1785
  if (this._frameloop === "demand") {
@@ -2343,16 +2482,329 @@ const _Scheduler = class _Scheduler {
2343
2482
  return /* @__PURE__ */ new Set([value]);
2344
2483
  }
2345
2484
  };
2346
- //* Static State & Methods (Singleton Usage) ================================
2347
- //* Cross-Bundle Singleton Key ==============================
2348
- // Use Symbol.for() to ensure scheduler is shared across bundle boundaries
2349
- // This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
2350
- __publicField(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
2351
- let Scheduler = _Scheduler;
2352
- const getScheduler = () => Scheduler.get();
2353
- if (hmrData) {
2354
- hmrData.accept?.();
2485
+ //* Static State & Methods (Singleton Usage) ================================
2486
+ //* Cross-Bundle Singleton Key ==============================
2487
+ // Use Symbol.for() to ensure scheduler is shared across bundle boundaries
2488
+ // This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
2489
+ __publicField$1(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
2490
+ let Scheduler = _Scheduler;
2491
+ const getScheduler = () => Scheduler.get();
2492
+ if (hmrData) {
2493
+ hmrData.accept?.();
2494
+ }
2495
+
2496
+ const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
2497
+ const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React__namespace.createContext(null));
2498
+ const createStore = (invalidate, advance) => {
2499
+ const rootStore = traditional.createWithEqualityFn((set, get) => {
2500
+ const position = new webgpu.Vector3();
2501
+ const defaultTarget = new webgpu.Vector3();
2502
+ const tempTarget = new webgpu.Vector3();
2503
+ function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
2504
+ const { width, height, top, left } = size;
2505
+ const aspect = width / height;
2506
+ if (target.isVector3) tempTarget.copy(target);
2507
+ else tempTarget.set(...target);
2508
+ const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
2509
+ if (isOrthographicCamera(camera)) {
2510
+ return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
2511
+ } else {
2512
+ const fov = camera.fov * Math.PI / 180;
2513
+ const h = 2 * Math.tan(fov / 2) * distance;
2514
+ const w = h * (width / height);
2515
+ return { width: w, height: h, top, left, factor: width / w, distance, aspect };
2516
+ }
2517
+ }
2518
+ let performanceTimeout = void 0;
2519
+ const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
2520
+ const pointer = new webgpu.Vector2();
2521
+ const rootState = {
2522
+ set,
2523
+ get,
2524
+ // Mock objects that have to be configured
2525
+ // primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
2526
+ primaryStore: null,
2527
+ gl: null,
2528
+ renderer: null,
2529
+ camera: null,
2530
+ frustum: new webgpu.Frustum(),
2531
+ autoUpdateFrustum: true,
2532
+ raycaster: null,
2533
+ events: { priority: 1, enabled: true, connected: false },
2534
+ scene: null,
2535
+ rootScene: null,
2536
+ xr: null,
2537
+ inspector: null,
2538
+ invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
2539
+ advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
2540
+ textureColorSpace: webgpu.SRGBColorSpace,
2541
+ isLegacy: false,
2542
+ webGPUSupported: false,
2543
+ isNative: false,
2544
+ controls: null,
2545
+ pointer,
2546
+ mouse: pointer,
2547
+ frameloop: "always",
2548
+ onPointerMissed: void 0,
2549
+ onDragOverMissed: void 0,
2550
+ onDropMissed: void 0,
2551
+ performance: {
2552
+ current: 1,
2553
+ min: 0.5,
2554
+ max: 1,
2555
+ debounce: 200,
2556
+ regress: () => {
2557
+ const state2 = get();
2558
+ if (performanceTimeout) clearTimeout(performanceTimeout);
2559
+ if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
2560
+ performanceTimeout = setTimeout(
2561
+ () => setPerformanceCurrent(get().performance.max),
2562
+ state2.performance.debounce
2563
+ );
2564
+ }
2565
+ },
2566
+ size: { width: 0, height: 0, top: 0, left: 0 },
2567
+ viewport: {
2568
+ initialDpr: 0,
2569
+ dpr: 0,
2570
+ width: 0,
2571
+ height: 0,
2572
+ top: 0,
2573
+ left: 0,
2574
+ aspect: 0,
2575
+ distance: 0,
2576
+ factor: 0,
2577
+ getCurrentViewport
2578
+ },
2579
+ setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
2580
+ setSize: (width, height, top, left) => {
2581
+ const state2 = get();
2582
+ if (width === void 0) {
2583
+ set({ _sizeImperative: false });
2584
+ if (state2._sizeProps) {
2585
+ const { width: propW, height: propH } = state2._sizeProps;
2586
+ if (propW !== void 0 || propH !== void 0) {
2587
+ const currentSize = state2.size;
2588
+ const newSize = {
2589
+ width: propW ?? currentSize.width,
2590
+ height: propH ?? currentSize.height,
2591
+ top: currentSize.top,
2592
+ left: currentSize.left
2593
+ };
2594
+ set((s) => ({
2595
+ size: newSize,
2596
+ viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
2597
+ }));
2598
+ getScheduler().invalidate();
2599
+ }
2600
+ }
2601
+ return;
2602
+ }
2603
+ const w = width;
2604
+ const h = height ?? width;
2605
+ const t = top ?? state2.size.top;
2606
+ const l = left ?? state2.size.left;
2607
+ const size = { width: w, height: h, top: t, left: l };
2608
+ set((s) => ({
2609
+ size,
2610
+ viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
2611
+ _sizeImperative: true
2612
+ }));
2613
+ getScheduler().invalidate();
2614
+ },
2615
+ setDpr: (dpr) => set((state2) => {
2616
+ const resolved = calculateDpr(dpr);
2617
+ return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
2618
+ }),
2619
+ setFrameloop: (frameloop = "always") => {
2620
+ set(() => ({ frameloop }));
2621
+ },
2622
+ setError: (error) => set(() => ({ error })),
2623
+ error: null,
2624
+ //* TSL State (managed via hooks: useUniforms, useNodes, useTextures, usePostProcessing) ==============================
2625
+ uniforms: {},
2626
+ nodes: {},
2627
+ textures: /* @__PURE__ */ new Map(),
2628
+ postProcessing: null,
2629
+ passes: {},
2630
+ _hmrVersion: 0,
2631
+ _sizeImperative: false,
2632
+ _sizeProps: null,
2633
+ previousRoot: void 0,
2634
+ internal: {
2635
+ // Events
2636
+ interaction: [],
2637
+ hovered: /* @__PURE__ */ new Map(),
2638
+ subscribers: [],
2639
+ initialClick: [0, 0],
2640
+ initialHits: [],
2641
+ capturedMap: /* @__PURE__ */ new Map(),
2642
+ lastEvent: React__namespace.createRef(),
2643
+ // Visibility tracking (onFramed, onOccluded, onVisible)
2644
+ visibilityRegistry: /* @__PURE__ */ new Map(),
2645
+ // Occlusion system (WebGPU only)
2646
+ occlusionEnabled: false,
2647
+ occlusionObserver: null,
2648
+ occlusionCache: /* @__PURE__ */ new Map(),
2649
+ helperGroup: null,
2650
+ // Updates
2651
+ active: false,
2652
+ frames: 0,
2653
+ priority: 0,
2654
+ subscribe: (ref, priority, store) => {
2655
+ const internal = get().internal;
2656
+ internal.priority = internal.priority + (priority > 0 ? 1 : 0);
2657
+ internal.subscribers.push({ ref, priority, store });
2658
+ internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
2659
+ return () => {
2660
+ const internal2 = get().internal;
2661
+ if (internal2?.subscribers) {
2662
+ internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
2663
+ internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
2664
+ }
2665
+ };
2666
+ },
2667
+ // Renderer Storage (single source of truth)
2668
+ actualRenderer: null,
2669
+ // Scheduler for useFrameNext (initialized in renderer.tsx)
2670
+ scheduler: null
2671
+ }
2672
+ };
2673
+ return rootState;
2674
+ });
2675
+ const state = rootStore.getState();
2676
+ Object.defineProperty(state, "gl", {
2677
+ get() {
2678
+ const currentState = rootStore.getState();
2679
+ if (!currentState.isLegacy && currentState.internal.actualRenderer) {
2680
+ const stack = new Error().stack || "";
2681
+ const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
2682
+ if (!isInternalAccess) {
2683
+ const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
2684
+ notifyDepreciated({
2685
+ heading: "Accessing state.gl in WebGPU mode",
2686
+ body: "Please use state.renderer instead. state.gl is deprecated and will be removed in future versions.\n\nFor backwards compatibility, state.gl currently maps to state.renderer, but this may cause issues with libraries expecting WebGLRenderer.\n\nAccessed from:\n" + cleanedStack
2687
+ });
2688
+ }
2689
+ }
2690
+ return currentState.internal.actualRenderer;
2691
+ },
2692
+ set(value) {
2693
+ rootStore.getState().internal.actualRenderer = value;
2694
+ },
2695
+ enumerable: true,
2696
+ configurable: true
2697
+ });
2698
+ Object.defineProperty(state, "renderer", {
2699
+ get() {
2700
+ return rootStore.getState().internal.actualRenderer;
2701
+ },
2702
+ set(value) {
2703
+ rootStore.getState().internal.actualRenderer = value;
2704
+ },
2705
+ enumerable: true,
2706
+ configurable: true
2707
+ });
2708
+ let oldScene = state.scene;
2709
+ rootStore.subscribe(() => {
2710
+ const currentState = rootStore.getState();
2711
+ const { scene, rootScene, set } = currentState;
2712
+ if (scene !== oldScene) {
2713
+ oldScene = scene;
2714
+ if (scene?.isScene && scene !== rootScene) {
2715
+ set({ rootScene: scene });
2716
+ }
2717
+ }
2718
+ });
2719
+ let oldSize = state.size;
2720
+ let oldDpr = state.viewport.dpr;
2721
+ let oldCamera = state.camera;
2722
+ rootStore.subscribe(() => {
2723
+ const { camera, size, viewport, set, internal } = rootStore.getState();
2724
+ const actualRenderer = internal.actualRenderer;
2725
+ const canvasTarget = internal.canvasTarget;
2726
+ if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
2727
+ oldSize = size;
2728
+ oldDpr = viewport.dpr;
2729
+ updateCamera(camera, size);
2730
+ if (canvasTarget) {
2731
+ if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
2732
+ const updateStyle = typeof HTMLCanvasElement !== "undefined" && canvasTarget.domElement instanceof HTMLCanvasElement;
2733
+ canvasTarget.setSize(size.width, size.height, updateStyle);
2734
+ } else {
2735
+ if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
2736
+ const updateStyle = typeof HTMLCanvasElement !== "undefined" && actualRenderer.domElement instanceof HTMLCanvasElement;
2737
+ actualRenderer.setSize(size.width, size.height, updateStyle);
2738
+ }
2739
+ }
2740
+ if (camera !== oldCamera) {
2741
+ oldCamera = camera;
2742
+ const { rootScene } = rootStore.getState();
2743
+ if (camera && rootScene && !camera.parent) {
2744
+ rootScene.add(camera);
2745
+ }
2746
+ set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
2747
+ const currentState = rootStore.getState();
2748
+ if (currentState.autoUpdateFrustum && camera) {
2749
+ updateFrustum(camera, currentState.frustum);
2750
+ }
2751
+ }
2752
+ });
2753
+ rootStore.subscribe((state2) => invalidate(state2));
2754
+ return rootStore;
2755
+ };
2756
+
2757
+ const memoizedLoaders = /* @__PURE__ */ new WeakMap();
2758
+ const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
2759
+ function getLoader(Proto) {
2760
+ if (isConstructor$1(Proto)) {
2761
+ let loader = memoizedLoaders.get(Proto);
2762
+ if (!loader) {
2763
+ loader = new Proto();
2764
+ memoizedLoaders.set(Proto, loader);
2765
+ }
2766
+ return loader;
2767
+ }
2768
+ return Proto;
2769
+ }
2770
+ function loadingFn(extensions, onProgress) {
2771
+ return function(Proto, input) {
2772
+ const loader = getLoader(Proto);
2773
+ if (extensions) extensions(loader);
2774
+ if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
2775
+ return loader.loadAsync(input, onProgress).then((data) => {
2776
+ if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
2777
+ return data;
2778
+ });
2779
+ }
2780
+ return new Promise(
2781
+ (res, reject) => loader.load(
2782
+ input,
2783
+ (data) => {
2784
+ if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
2785
+ res(data);
2786
+ },
2787
+ onProgress,
2788
+ (error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
2789
+ )
2790
+ );
2791
+ };
2792
+ }
2793
+ function useLoader(loader, input, extensions, onProgress) {
2794
+ const keys = Array.isArray(input) ? input : [input];
2795
+ const fn = loadingFn(extensions, onProgress);
2796
+ const results = keys.map((key) => suspendReact.suspend(fn, [loader, key], { equal: is.equ }));
2797
+ return Array.isArray(input) ? results : results[0];
2355
2798
  }
2799
+ useLoader.preload = function(loader, input, extensions, onProgress) {
2800
+ const keys = Array.isArray(input) ? input : [input];
2801
+ keys.forEach((key) => suspendReact.preload(loadingFn(extensions, onProgress), [loader, key]));
2802
+ };
2803
+ useLoader.clear = function(loader, input) {
2804
+ const keys = Array.isArray(input) ? input : [input];
2805
+ keys.forEach((key) => suspendReact.clear([loader, key]));
2806
+ };
2807
+ useLoader.loader = getLoader;
2356
2808
 
2357
2809
  function useFrame(callback, priorityOrOptions) {
2358
2810
  const store = React__namespace.useContext(context);
@@ -2533,6 +2985,9 @@ function useTexture(input, optionsOrOnLoad) {
2533
2985
  const textureCache = useThree((state) => state.textures);
2534
2986
  const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
2535
2987
  const { onLoad, cache = false } = options;
2988
+ const onLoadRef = React.useRef(onLoad);
2989
+ onLoadRef.current = onLoad;
2990
+ const onLoadCalledForRef = React.useRef(null);
2536
2991
  const urls = React.useMemo(() => getUrls(input), [input]);
2537
2992
  const cachedResult = React.useMemo(() => {
2538
2993
  if (!cache) return null;
@@ -2543,9 +2998,13 @@ function useTexture(input, optionsOrOnLoad) {
2543
2998
  webgpu.TextureLoader,
2544
2999
  IsObject(input) ? Object.values(input) : input
2545
3000
  );
3001
+ const inputKey = urls.join("\0");
2546
3002
  React.useLayoutEffect(() => {
2547
- if (!cachedResult) onLoad?.(loadedTextures);
2548
- }, [onLoad, cachedResult, loadedTextures]);
3003
+ if (cachedResult) return;
3004
+ if (onLoadCalledForRef.current === inputKey) return;
3005
+ onLoadCalledForRef.current = inputKey;
3006
+ onLoadRef.current?.(loadedTextures);
3007
+ }, [cachedResult, loadedTextures, inputKey]);
2549
3008
  React.useEffect(() => {
2550
3009
  if (cachedResult) return;
2551
3010
  if ("initTexture" in renderer) {
@@ -2712,14 +3171,31 @@ function useTextures() {
2712
3171
  }, [store]);
2713
3172
  }
2714
3173
 
2715
- function useRenderTarget(width, height, options) {
3174
+ function useRenderTarget(widthOrOptions, heightOrOptions, options) {
2716
3175
  const isLegacy = useThree((s) => s.isLegacy);
2717
3176
  const size = useThree((s) => s.size);
3177
+ let width;
3178
+ let height;
3179
+ let opts;
3180
+ if (typeof widthOrOptions === "object") {
3181
+ opts = widthOrOptions;
3182
+ } else if (typeof widthOrOptions === "number") {
3183
+ width = widthOrOptions;
3184
+ if (typeof heightOrOptions === "object") {
3185
+ height = widthOrOptions;
3186
+ opts = heightOrOptions;
3187
+ } else if (typeof heightOrOptions === "number") {
3188
+ height = heightOrOptions;
3189
+ opts = options;
3190
+ } else {
3191
+ height = widthOrOptions;
3192
+ }
3193
+ }
2718
3194
  return React.useMemo(() => {
2719
3195
  const w = width ?? size.width;
2720
3196
  const h = height ?? size.height;
2721
- return new webgpu.RenderTarget(w, h, options);
2722
- }, [width, height, size.width, size.height, options, isLegacy]);
3197
+ return new webgpu.RenderTarget(w, h, opts);
3198
+ }, [width, height, size.width, size.height, opts, isLegacy]);
2723
3199
  }
2724
3200
 
2725
3201
  function useStore() {
@@ -2769,28 +3245,18 @@ function addTail(callback) {
2769
3245
  function invalidate(state, frames = 1, stackFrames = false) {
2770
3246
  getScheduler().invalidate(frames, stackFrames);
2771
3247
  }
2772
- function advance(timestamp, runGlobalEffects = true, state, frame) {
3248
+ function advance(timestamp) {
2773
3249
  getScheduler().step(timestamp);
2774
3250
  }
2775
3251
 
2776
- const version = "10.0.0-alpha.1";
3252
+ const version = "10.0.0-alpha.2";
2777
3253
  const packageData = {
2778
3254
  version: version};
2779
3255
 
2780
3256
  function Xb(Tt) {
2781
3257
  return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
2782
3258
  }
2783
- var Rm = { exports: {} }, Og = { exports: {} };
2784
- /**
2785
- * @license React
2786
- * react-reconciler.production.js
2787
- *
2788
- * Copyright (c) Meta Platforms, Inc. and affiliates.
2789
- *
2790
- * This source code is licensed under the MIT license found in the
2791
- * LICENSE file in the root directory of this source tree.
2792
- */
2793
- var _b;
3259
+ var Rm = { exports: {} }, Og = { exports: {} }, _b;
2794
3260
  function Kb() {
2795
3261
  return _b || (_b = 1, (function(Tt) {
2796
3262
  Tt.exports = function(m) {
@@ -3862,7 +4328,6 @@ Error generating stack: ` + l.message + `
3862
4328
  if (J === cl || J === jc) throw J;
3863
4329
  var Ge = Yn(29, J, null, P.mode);
3864
4330
  return Ge.lanes = H, Ge.return = P, Ge;
3865
- } finally {
3866
4331
  }
3867
4332
  };
3868
4333
  }
@@ -4516,7 +4981,6 @@ Error generating stack: ` + l.message + `
4516
4981
  var h = r.lastRenderedState, y = d(h, a);
4517
4982
  if (c.hasEagerState = true, c.eagerState = y, jn(y, h)) return go(t, r, c, 0), Ne === null && Bn(), false;
4518
4983
  } catch {
4519
- } finally {
4520
4984
  }
4521
4985
  if (a = yo(t, r, c, l), a !== null) return nt(a, t, l), ns(a, r, l), true;
4522
4986
  }
@@ -6937,10 +7401,7 @@ Error generating stack: ` + l.message + `
6937
7401
  function vr(t, r) {
6938
7402
  Sf(t, r), (t = t.alternate) && Sf(t, r);
6939
7403
  }
6940
- var ie = {}, Fm = React__default, tt = Tb__default, Lt = Object.assign, hc = Symbol.for("react.element"), zs = Symbol.for("react.transitional.element"), sa = Symbol.for("react.portal"), $a = Symbol.for("react.fragment"), kf = Symbol.for("react.strict_mode"), Cs = Symbol.for("react.profiler"), mc = Symbol.for("react.consumer"), Io = Symbol.for("react.context"), Zi = Symbol.for("react.forward_ref"), Va = Symbol.for("react.suspense"), Te = Symbol.for("react.suspense_list"), wf = Symbol.for("react.memo"), ua = Symbol.for("react.lazy");
6941
- var gc = Symbol.for("react.activity");
6942
- var $r = Symbol.for("react.memo_cache_sentinel");
6943
- var Pf = Symbol.iterator, xf = Symbol.for("react.client.reference"), ca = Array.isArray, M = Fm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Yp = m.rendererVersion, zf = m.rendererPackageName, Cf = m.extraDevToolsConfig, Ts = m.getPublicInstance, Hm = m.getRootHostContext, Xp = m.getChildHostContext, Am = m.prepareForCommit, _s = m.resetAfterCommit, Vr = m.createInstance;
7404
+ var ie = {}, Fm = React__default, tt = Tb__default, Lt = Object.assign, hc = Symbol.for("react.element"), zs = Symbol.for("react.transitional.element"), sa = Symbol.for("react.portal"), $a = Symbol.for("react.fragment"), kf = Symbol.for("react.strict_mode"), Cs = Symbol.for("react.profiler"), mc = Symbol.for("react.consumer"), Io = Symbol.for("react.context"), Zi = Symbol.for("react.forward_ref"), Va = Symbol.for("react.suspense"), Te = Symbol.for("react.suspense_list"), wf = Symbol.for("react.memo"), ua = Symbol.for("react.lazy"), gc = Symbol.for("react.activity"), $r = Symbol.for("react.memo_cache_sentinel"), Pf = Symbol.iterator, xf = Symbol.for("react.client.reference"), ca = Array.isArray, M = Fm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Yp = m.rendererVersion, zf = m.rendererPackageName, Cf = m.extraDevToolsConfig, Ts = m.getPublicInstance, Hm = m.getRootHostContext, Xp = m.getChildHostContext, Am = m.prepareForCommit, _s = m.resetAfterCommit, Vr = m.createInstance;
6944
7405
  m.cloneMutableInstance;
6945
7406
  var yc = m.appendInitialChild, Kp = m.finalizeInitialChildren, Rs = m.shouldSetTextContent, bc = m.createTextInstance;
6946
7407
  m.cloneMutableTextInstance;
@@ -7309,17 +7770,7 @@ No matching component was found for:
7309
7770
  }, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true });
7310
7771
  })(Og)), Og.exports;
7311
7772
  }
7312
- var Mg = { exports: {} };
7313
- /**
7314
- * @license React
7315
- * react-reconciler.development.js
7316
- *
7317
- * Copyright (c) Meta Platforms, Inc. and affiliates.
7318
- *
7319
- * This source code is licensed under the MIT license found in the
7320
- * LICENSE file in the root directory of this source tree.
7321
- */
7322
- var Rb;
7773
+ var Mg = { exports: {} }, Rb;
7323
7774
  function e0() {
7324
7775
  return Rb || (Rb = 1, (function(Tt) {
7325
7776
  process.env.NODE_ENV !== "production" && (Tt.exports = function(m) {
@@ -13086,10 +13537,7 @@ Check the render method of %s.`, G(di) || "Unknown")), i = zo(n), i.payload = {
13086
13537
  function Ic() {
13087
13538
  return di;
13088
13539
  }
13089
- var le = {}, qm = React__default, St = Tb__default, ze = Object.assign, Uh = Symbol.for("react.element"), Ho = Symbol.for("react.transitional.element"), Ao = Symbol.for("react.portal"), ol = Symbol.for("react.fragment"), Lc = Symbol.for("react.strict_mode"), Uf = Symbol.for("react.profiler"), ei = Symbol.for("react.consumer"), on = Symbol.for("react.context"), jn = Symbol.for("react.forward_ref"), Nc = Symbol.for("react.suspense"), Bf = Symbol.for("react.suspense_list"), al = Symbol.for("react.memo"), kt = Symbol.for("react.lazy");
13090
- var Ds = Symbol.for("react.activity");
13091
- var Bh = Symbol.for("react.memo_cache_sentinel");
13092
- var ni = Symbol.iterator, il = Symbol.for("react.client.reference"), fn = Array.isArray, x = qm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Jt = m.rendererVersion, Zt = m.rendererPackageName, jo = m.extraDevToolsConfig, ot = m.getPublicInstance, Zr = m.getRootHostContext, Dn = m.getChildHostContext, Ws = m.prepareForCommit, pa = m.resetAfterCommit, Fc = m.createInstance;
13540
+ var le = {}, qm = React__default, St = Tb__default, ze = Object.assign, Uh = Symbol.for("react.element"), Ho = Symbol.for("react.transitional.element"), Ao = Symbol.for("react.portal"), ol = Symbol.for("react.fragment"), Lc = Symbol.for("react.strict_mode"), Uf = Symbol.for("react.profiler"), ei = Symbol.for("react.consumer"), on = Symbol.for("react.context"), jn = Symbol.for("react.forward_ref"), Nc = Symbol.for("react.suspense"), Bf = Symbol.for("react.suspense_list"), al = Symbol.for("react.memo"), kt = Symbol.for("react.lazy"), Ds = Symbol.for("react.activity"), Bh = Symbol.for("react.memo_cache_sentinel"), ni = Symbol.iterator, il = Symbol.for("react.client.reference"), fn = Array.isArray, x = qm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Jt = m.rendererVersion, Zt = m.rendererPackageName, jo = m.extraDevToolsConfig, ot = m.getPublicInstance, Zr = m.getRootHostContext, Dn = m.getChildHostContext, Ws = m.prepareForCommit, pa = m.resetAfterCommit, Fc = m.createInstance;
13093
13541
  m.cloneMutableInstance;
13094
13542
  var bn = m.appendInitialChild, Ue = m.finalizeInitialChildren, ue = m.shouldSetTextContent, Do = m.createTextInstance;
13095
13543
  m.cloneMutableTextInstance;
@@ -14057,15 +14505,6 @@ function n0() {
14057
14505
  var t0 = n0();
14058
14506
  const r0 = Xb(t0);
14059
14507
 
14060
- /**
14061
- * @license React
14062
- * react-reconciler-constants.production.js
14063
- *
14064
- * Copyright (c) Meta Platforms, Inc. and affiliates.
14065
- *
14066
- * This source code is licensed under the MIT license found in the
14067
- * LICENSE file in the root directory of this source tree.
14068
- */
14069
14508
  const t = 1, o = 8, r = 32, e = 2;
14070
14509
 
14071
14510
  function createReconciler(config) {
@@ -14092,10 +14531,11 @@ function extend(objects) {
14092
14531
  function validateInstance(type, props) {
14093
14532
  const name = toPascalCase(type);
14094
14533
  const target = catalogue[name];
14095
- if (type !== "primitive" && !target)
14534
+ if (type !== "primitive" && !target) {
14096
14535
  throw new Error(
14097
14536
  `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`
14098
14537
  );
14538
+ }
14099
14539
  if (type === "primitive" && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`);
14100
14540
  if (props.args !== void 0 && !Array.isArray(props.args)) throw new Error("R3F: The args prop must be an array!");
14101
14541
  }
@@ -14259,6 +14699,7 @@ function swapInstances() {
14259
14699
  instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
14260
14700
  instance.object.__r3f = instance;
14261
14701
  setFiberRef(fiber, instance.object);
14702
+ delete instance.appliedOnce;
14262
14703
  applyProps(instance.object, instance.props);
14263
14704
  if (instance.props.attach) {
14264
14705
  attach(parent, instance);
@@ -14332,8 +14773,22 @@ const reconciler = /* @__PURE__ */ createReconciler({
14332
14773
  const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
14333
14774
  if (isTailSibling) swapInstances();
14334
14775
  },
14335
- finalizeInitialChildren: () => false,
14336
- commitMount() {
14776
+ finalizeInitialChildren: (instance) => {
14777
+ for (const prop in instance.props) {
14778
+ if (isFromRef(instance.props[prop])) return true;
14779
+ }
14780
+ return false;
14781
+ },
14782
+ commitMount(instance) {
14783
+ const resolved = {};
14784
+ for (const prop in instance.props) {
14785
+ const value = instance.props[prop];
14786
+ if (isFromRef(value)) {
14787
+ const ref = value[FROM_REF];
14788
+ if (ref.current != null) resolved[prop] = ref.current;
14789
+ }
14790
+ }
14791
+ if (Object.keys(resolved).length) applyProps(instance.object, resolved);
14337
14792
  },
14338
14793
  getPublicInstance: (instance) => instance?.object,
14339
14794
  prepareForCommit: () => null,
@@ -14546,14 +15001,17 @@ function createRoot(canvas) {
14546
15001
  if (!prevRoot) _roots.set(canvas, { fiber, store });
14547
15002
  let onCreated;
14548
15003
  let lastCamera;
14549
- let lastConfiguredProps = {};
15004
+ const lastConfiguredProps = {};
14550
15005
  let configured = false;
14551
15006
  let pending = null;
14552
15007
  return {
14553
15008
  async configure(props = {}) {
14554
15009
  let resolve;
14555
15010
  pending = new Promise((_resolve) => resolve = _resolve);
14556
- let {
15011
+ const {
15012
+ id: canvasId,
15013
+ primaryCanvas,
15014
+ scheduler: schedulerConfig,
14557
15015
  gl: glConfig,
14558
15016
  renderer: rendererConfig,
14559
15017
  size: propsSize,
@@ -14561,10 +15019,7 @@ function createRoot(canvas) {
14561
15019
  events,
14562
15020
  onCreated: onCreatedCallback,
14563
15021
  shadows = false,
14564
- linear = false,
14565
- flat = false,
14566
15022
  textureColorSpace = webgpu.SRGBColorSpace,
14567
- legacy = false,
14568
15023
  orthographic = false,
14569
15024
  frameloop = "always",
14570
15025
  dpr = [1, 2],
@@ -14575,11 +15030,14 @@ function createRoot(canvas) {
14575
15030
  onDragOverMissed,
14576
15031
  onDropMissed,
14577
15032
  autoUpdateFrustum = true,
14578
- occlusion = false
15033
+ occlusion = false,
15034
+ _sizeProps,
15035
+ forceEven
14579
15036
  } = props;
14580
- let state = store.getState();
15037
+ const state = store.getState();
14581
15038
  const defaultGPUProps = {
14582
- canvas
15039
+ canvas,
15040
+ antialias: true
14583
15041
  };
14584
15042
  if (glConfig && !R3F_BUILD_LEGACY) {
14585
15043
  throw new Error(
@@ -14590,7 +15048,27 @@ function createRoot(canvas) {
14590
15048
  throw new Error("Cannot use both gl and renderer props at the same time");
14591
15049
  }
14592
15050
  let renderer = state.internal.actualRenderer;
14593
- if (!state.internal.actualRenderer) {
15051
+ if (primaryCanvas && !state.internal.actualRenderer) {
15052
+ const primary = await waitForPrimary(primaryCanvas);
15053
+ renderer = primary.renderer;
15054
+ state.internal.actualRenderer = renderer;
15055
+ const canvasTarget = new webgpu.CanvasTarget(canvas);
15056
+ primary.store.setState((prev) => ({
15057
+ internal: { ...prev.internal, isMultiCanvas: true }
15058
+ }));
15059
+ state.set((prev) => ({
15060
+ webGPUSupported: primary.store.getState().webGPUSupported,
15061
+ renderer,
15062
+ primaryStore: primary.store,
15063
+ internal: {
15064
+ ...prev.internal,
15065
+ canvasTarget,
15066
+ isMultiCanvas: true,
15067
+ isSecondary: true,
15068
+ targetId: primaryCanvas
15069
+ }
15070
+ }));
15071
+ } else if (!state.internal.actualRenderer) {
14594
15072
  renderer = await resolveRenderer(rendererConfig, defaultGPUProps, webgpu.WebGPURenderer);
14595
15073
  if (!renderer.hasInitialized?.()) {
14596
15074
  await renderer.init();
@@ -14598,14 +15076,27 @@ function createRoot(canvas) {
14598
15076
  const backend = renderer.backend;
14599
15077
  const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
14600
15078
  state.internal.actualRenderer = renderer;
14601
- state.set({ webGPUSupported: isWebGPUBackend, renderer });
15079
+ state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
15080
+ if (canvasId && !state.internal.isSecondary) {
15081
+ const canvasTarget = new webgpu.CanvasTarget(canvas);
15082
+ const unregisterPrimary = registerPrimary(canvasId, renderer, store);
15083
+ state.set((prev) => ({
15084
+ internal: {
15085
+ ...prev.internal,
15086
+ canvasTarget,
15087
+ unregisterPrimary
15088
+ }
15089
+ }));
15090
+ }
14602
15091
  }
14603
15092
  let raycaster = state.raycaster;
14604
15093
  if (!raycaster) state.set({ raycaster: raycaster = new webgpu.Raycaster() });
14605
15094
  const { params, ...options } = raycastOptions || {};
14606
15095
  if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options });
14607
- if (!is.equ(params, raycaster.params, shallowLoose))
15096
+ if (!is.equ(params, raycaster.params, shallowLoose)) {
14608
15097
  applyProps(raycaster, { params: { ...raycaster.params, ...params } });
15098
+ }
15099
+ let tempCamera = state.camera;
14609
15100
  if (!state.camera || state.camera === lastCamera && !is.equ(lastCamera, cameraOptions, shallowLoose)) {
14610
15101
  lastCamera = cameraOptions;
14611
15102
  const isCamera = cameraOptions?.isCamera;
@@ -14625,6 +15116,7 @@ function createRoot(canvas) {
14625
15116
  if (!state.camera && !cameraOptions?.rotation) camera.lookAt(0, 0, 0);
14626
15117
  }
14627
15118
  state.set({ camera });
15119
+ tempCamera = camera;
14628
15120
  raycaster.camera = camera;
14629
15121
  }
14630
15122
  if (!state.scene) {
@@ -14642,7 +15134,7 @@ function createRoot(canvas) {
14642
15134
  rootScene: scene,
14643
15135
  internal: { ...prev.internal, container: scene }
14644
15136
  }));
14645
- const camera = state.camera;
15137
+ const camera = tempCamera;
14646
15138
  if (camera && !camera.parent) scene.add(camera);
14647
15139
  }
14648
15140
  if (events && !state.events.handlers) {
@@ -14656,9 +15148,17 @@ function createRoot(canvas) {
14656
15148
  wasEnabled = enabled;
14657
15149
  });
14658
15150
  }
15151
+ if (_sizeProps !== void 0) {
15152
+ state.set({ _sizeProps });
15153
+ }
15154
+ if (forceEven !== void 0 && state.internal.forceEven !== forceEven) {
15155
+ state.set((prev) => ({ internal: { ...prev.internal, forceEven } }));
15156
+ }
14659
15157
  const size = computeInitialSize(canvas, propsSize);
14660
- if (!is.equ(size, state.size, shallowLoose)) {
15158
+ if (!state._sizeImperative && !is.equ(size, state.size, shallowLoose)) {
15159
+ const wasImperative = state._sizeImperative;
14661
15160
  state.setSize(size.width, size.height, size.top, size.left);
15161
+ if (!wasImperative) state.set({ _sizeImperative: false });
14662
15162
  }
14663
15163
  if (dpr !== void 0 && !is.equ(dpr, lastConfiguredProps.dpr, shallowLoose)) {
14664
15164
  state.setDpr(dpr);
@@ -14683,7 +15183,7 @@ function createRoot(canvas) {
14683
15183
  const handleXRFrame = (timestamp, frame) => {
14684
15184
  const state2 = store.getState();
14685
15185
  if (state2.frameloop === "never") return;
14686
- advance(timestamp, true);
15186
+ advance(timestamp);
14687
15187
  };
14688
15188
  const actualRenderer = state.internal.actualRenderer;
14689
15189
  const handleSessionChange = () => {
@@ -14695,16 +15195,16 @@ function createRoot(canvas) {
14695
15195
  };
14696
15196
  const xr = {
14697
15197
  connect() {
14698
- const { gl, renderer: renderer2, isLegacy } = store.getState();
14699
- const actualRenderer2 = renderer2 || gl;
14700
- actualRenderer2.xr.addEventListener("sessionstart", handleSessionChange);
14701
- actualRenderer2.xr.addEventListener("sessionend", handleSessionChange);
15198
+ const { gl, renderer: renderer2 } = store.getState();
15199
+ const xrManager = (renderer2 || gl).xr;
15200
+ xrManager.addEventListener("sessionstart", handleSessionChange);
15201
+ xrManager.addEventListener("sessionend", handleSessionChange);
14702
15202
  },
14703
15203
  disconnect() {
14704
- const { gl, renderer: renderer2, isLegacy } = store.getState();
14705
- const actualRenderer2 = renderer2 || gl;
14706
- actualRenderer2.xr.removeEventListener("sessionstart", handleSessionChange);
14707
- actualRenderer2.xr.removeEventListener("sessionend", handleSessionChange);
15204
+ const { gl, renderer: renderer2 } = store.getState();
15205
+ const xrManager = (renderer2 || gl).xr;
15206
+ xrManager.removeEventListener("sessionstart", handleSessionChange);
15207
+ xrManager.removeEventListener("sessionend", handleSessionChange);
14708
15208
  }
14709
15209
  };
14710
15210
  if (typeof renderer.xr?.addEventListener === "function") xr.connect();
@@ -14728,15 +15228,21 @@ function createRoot(canvas) {
14728
15228
  } else if (is.obj(shadows)) {
14729
15229
  Object.assign(renderer.shadowMap, shadows);
14730
15230
  }
14731
- if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type)
15231
+ if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type) {
14732
15232
  renderer.shadowMap.needsUpdate = true;
15233
+ }
15234
+ }
15235
+ if (!configured) {
15236
+ renderer.outputColorSpace = webgpu.SRGBColorSpace;
15237
+ renderer.toneMapping = webgpu.ACESFilmicToneMapping;
14733
15238
  }
14734
15239
  if (textureColorSpace !== lastConfiguredProps.textureColorSpace) {
14735
15240
  if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
14736
15241
  lastConfiguredProps.textureColorSpace = textureColorSpace;
14737
15242
  }
14738
- if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose))
15243
+ if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose)) {
14739
15244
  applyProps(renderer, glConfig);
15245
+ }
14740
15246
  if (rendererConfig && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && state.renderer) {
14741
15247
  const currentRenderer = state.renderer;
14742
15248
  if (!is.equ(rendererConfig, currentRenderer, shallowLoose)) {
@@ -14746,11 +15252,26 @@ function createRoot(canvas) {
14746
15252
  const scheduler = getScheduler();
14747
15253
  const rootId = state.internal.rootId;
14748
15254
  if (!rootId) {
14749
- const newRootId = scheduler.generateRootId();
15255
+ const newRootId = canvasId || scheduler.generateRootId();
14750
15256
  const unregisterRoot = scheduler.registerRoot(newRootId, {
14751
15257
  getState: () => store.getState(),
14752
15258
  onError: (err) => store.getState().setError(err)
14753
15259
  });
15260
+ const unregisterCanvasTarget = scheduler.register(
15261
+ () => {
15262
+ const state2 = store.getState();
15263
+ if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
15264
+ const renderer2 = state2.internal.actualRenderer;
15265
+ renderer2.setCanvasTarget(state2.internal.canvasTarget);
15266
+ }
15267
+ },
15268
+ {
15269
+ id: `${newRootId}_canvasTarget`,
15270
+ rootId: newRootId,
15271
+ phase: "start",
15272
+ system: true
15273
+ }
15274
+ );
14754
15275
  const unregisterFrustum = scheduler.register(
14755
15276
  () => {
14756
15277
  const state2 = store.getState();
@@ -14792,11 +15313,15 @@ function createRoot(canvas) {
14792
15313
  }
14793
15314
  },
14794
15315
  {
14795
- id: `${newRootId}_render`,
15316
+ // Use canvas ID directly as job ID if available, otherwise use generated rootId
15317
+ id: canvasId || `${newRootId}_render`,
14796
15318
  rootId: newRootId,
14797
15319
  phase: "render",
14798
- system: true
15320
+ system: true,
14799
15321
  // Internal flag: this is a system job, not user-controlled
15322
+ // Apply scheduler config for render ordering and rate limiting
15323
+ ...schedulerConfig?.after && { after: schedulerConfig.after },
15324
+ ...schedulerConfig?.fps && { fps: schedulerConfig.fps }
14800
15325
  }
14801
15326
  );
14802
15327
  state.set((state2) => ({
@@ -14805,6 +15330,7 @@ function createRoot(canvas) {
14805
15330
  rootId: newRootId,
14806
15331
  unregisterRoot: () => {
14807
15332
  unregisterRoot();
15333
+ unregisterCanvasTarget();
14808
15334
  unregisterFrustum();
14809
15335
  unregisterVisibility();
14810
15336
  unregisterRender();
@@ -14863,15 +15389,24 @@ function unmountComponentAtNode(canvas, callback) {
14863
15389
  const renderer = state.internal.actualRenderer;
14864
15390
  const unregisterRoot = state.internal.unregisterRoot;
14865
15391
  if (unregisterRoot) unregisterRoot();
15392
+ const unregisterPrimary = state.internal.unregisterPrimary;
15393
+ if (unregisterPrimary) unregisterPrimary();
15394
+ const canvasTarget = state.internal.canvasTarget;
15395
+ if (canvasTarget?.dispose) canvasTarget.dispose();
14866
15396
  state.events.disconnect?.();
14867
15397
  cleanupHelperGroup(root.store);
14868
- renderer?.renderLists?.dispose?.();
14869
- renderer?.forceContextLoss?.();
14870
- if (renderer?.xr) state.xr.disconnect();
15398
+ if (state.isLegacy && renderer) {
15399
+ ;
15400
+ renderer.renderLists?.dispose?.();
15401
+ renderer.forceContextLoss?.();
15402
+ }
15403
+ if (!state.internal.isSecondary) {
15404
+ if (renderer?.xr) state.xr.disconnect();
15405
+ }
14871
15406
  dispose(state.scene);
14872
15407
  _roots.delete(canvas);
14873
15408
  if (callback) callback(canvas);
14874
- } catch (e) {
15409
+ } catch {
14875
15410
  }
14876
15411
  }, 500);
14877
15412
  }
@@ -14879,36 +15414,34 @@ function unmountComponentAtNode(canvas, callback) {
14879
15414
  }
14880
15415
  }
14881
15416
  function createPortal(children, container, state) {
14882
- return /* @__PURE__ */ jsxRuntime.jsx(PortalWrapper, { children, container, state });
15417
+ return /* @__PURE__ */ jsxRuntime.jsx(Portal, { children, container, state });
14883
15418
  }
14884
- function PortalWrapper({ children, container, state }) {
15419
+ function Portal({ children, container, state }) {
14885
15420
  const isRef = React.useCallback((obj) => obj && "current" in obj, []);
14886
- const [resolvedContainer, setResolvedContainer] = React.useState(() => {
15421
+ const [resolvedContainer, _setResolvedContainer] = React.useState(() => {
14887
15422
  if (isRef(container)) return container.current ?? null;
14888
15423
  return container;
14889
15424
  });
15425
+ const setResolvedContainer = React.useCallback(
15426
+ (newContainer) => {
15427
+ if (!newContainer || newContainer === resolvedContainer) return;
15428
+ _setResolvedContainer(isRef(newContainer) ? newContainer.current : newContainer);
15429
+ },
15430
+ [resolvedContainer, _setResolvedContainer, isRef]
15431
+ );
14890
15432
  React.useMemo(() => {
14891
- if (isRef(container)) {
14892
- const current = container.current;
14893
- if (!current) {
14894
- queueMicrotask(() => {
14895
- const updated = container.current;
14896
- if (updated && updated !== resolvedContainer) {
14897
- setResolvedContainer(updated);
14898
- }
14899
- });
14900
- } else if (current !== resolvedContainer) {
14901
- setResolvedContainer(current);
14902
- }
14903
- } else if (container !== resolvedContainer) {
14904
- setResolvedContainer(container);
15433
+ if (isRef(container) && !container.current) {
15434
+ return queueMicrotask(() => {
15435
+ setResolvedContainer(container.current);
15436
+ });
14905
15437
  }
14906
- }, [container, resolvedContainer, isRef]);
15438
+ setResolvedContainer(container);
15439
+ }, [container, isRef, setResolvedContainer]);
14907
15440
  if (!resolvedContainer) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
14908
15441
  const portalKey = resolvedContainer.uuid ?? `portal-${resolvedContainer.id ?? "unknown"}`;
14909
- return /* @__PURE__ */ jsxRuntime.jsx(Portal, { children, container: resolvedContainer, state }, portalKey);
15442
+ return /* @__PURE__ */ jsxRuntime.jsx(PortalInner, { children, container: resolvedContainer, state }, portalKey);
14910
15443
  }
14911
- function Portal({ state = {}, children, container }) {
15444
+ function PortalInner({ state = {}, children, container }) {
14912
15445
  const { events, size, injectScene = true, ...rest } = state;
14913
15446
  const previousRoot = useStore();
14914
15447
  const [raycaster] = React.useState(() => new webgpu.Raycaster());
@@ -14929,11 +15462,12 @@ function Portal({ state = {}, children, container }) {
14929
15462
  };
14930
15463
  }, [portalScene, container, injectScene]);
14931
15464
  const inject = useMutableCallback((rootState, injectState) => {
15465
+ const resolvedSize = { ...rootState.size, ...injectState.size, ...size };
14932
15466
  let viewport = void 0;
14933
- if (injectState.camera && size) {
15467
+ if (injectState.camera && (size || injectState.size)) {
14934
15468
  const camera = injectState.camera;
14935
- viewport = rootState.viewport.getCurrentViewport(camera, new webgpu.Vector3(), size);
14936
- if (camera !== rootState.camera) updateCamera(camera, size);
15469
+ viewport = rootState.viewport.getCurrentViewport(camera, new webgpu.Vector3(), resolvedSize);
15470
+ if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
14937
15471
  }
14938
15472
  return {
14939
15473
  // The intersect consists of the previous root state
@@ -14950,7 +15484,7 @@ function Portal({ state = {}, children, container }) {
14950
15484
  previousRoot,
14951
15485
  // Events, size and viewport can be overridden by the inject layer
14952
15486
  events: { ...rootState.events, ...injectState.events, ...events },
14953
- size: { ...rootState.size, ...size },
15487
+ size: resolvedSize,
14954
15488
  viewport: { ...rootState.viewport, ...viewport },
14955
15489
  // Layers are allowed to override events
14956
15490
  setEvents: (events2) => injectState.set((state2) => ({ ...state2, events: { ...state2.events, ...events2 } })),
@@ -14984,15 +15518,13 @@ function CanvasImpl({
14984
15518
  fallback,
14985
15519
  resize,
14986
15520
  style,
15521
+ id,
14987
15522
  gl,
14988
- renderer,
15523
+ renderer: rendererProp,
14989
15524
  events = createPointerEvents,
14990
15525
  eventSource,
14991
15526
  eventPrefix,
14992
15527
  shadows,
14993
- linear,
14994
- flat,
14995
- legacy,
14996
15528
  orthographic,
14997
15529
  frameloop,
14998
15530
  dpr,
@@ -15004,10 +15536,46 @@ function CanvasImpl({
15004
15536
  onDragOverMissed,
15005
15537
  onDropMissed,
15006
15538
  onCreated,
15539
+ hmr,
15540
+ width,
15541
+ height,
15542
+ background,
15543
+ forceEven,
15007
15544
  ...props
15008
15545
  }) {
15546
+ const { primaryCanvas, scheduler, ...rendererConfig } = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp) ? rendererProp : { primaryCanvas: void 0, scheduler: void 0 };
15547
+ const renderer = Object.keys(rendererConfig).length > 0 ? rendererConfig : rendererProp;
15009
15548
  React__namespace.useMemo(() => extend(THREE), []);
15010
15549
  const Bridge = useBridge();
15550
+ const backgroundProps = React__namespace.useMemo(() => {
15551
+ if (!background) return null;
15552
+ if (typeof background === "object" && !background.isColor) {
15553
+ const { backgroundMap, envMap, files, preset, ...rest } = background;
15554
+ return {
15555
+ ...rest,
15556
+ preset,
15557
+ files: envMap || files,
15558
+ backgroundFiles: backgroundMap,
15559
+ background: true
15560
+ };
15561
+ }
15562
+ if (typeof background === "number") {
15563
+ return { color: background, background: true };
15564
+ }
15565
+ if (typeof background === "string") {
15566
+ if (background in presetsObj) {
15567
+ return { preset: background, background: true };
15568
+ }
15569
+ if (/^(https?:\/\/|\/|\.\/|\.\.\/)|\\.(hdr|exr|jpg|jpeg|png|webp|gif)$/i.test(background)) {
15570
+ return { files: background, background: true };
15571
+ }
15572
+ return { color: background, background: true };
15573
+ }
15574
+ if (background.isColor) {
15575
+ return { color: background, background: true };
15576
+ }
15577
+ return null;
15578
+ }, [background]);
15011
15579
  const hasInitialSizeRef = React__namespace.useRef(false);
15012
15580
  const measureConfig = React__namespace.useMemo(() => {
15013
15581
  if (!hasInitialSizeRef.current) {
@@ -15024,7 +15592,21 @@ function CanvasImpl({
15024
15592
  };
15025
15593
  }, [resize, hasInitialSizeRef.current]);
15026
15594
  const [containerRef, containerRect] = useMeasure__default(measureConfig);
15027
- if (!hasInitialSizeRef.current && containerRect.width > 0 && containerRect.height > 0) {
15595
+ const effectiveSize = React__namespace.useMemo(() => {
15596
+ let w = width ?? containerRect.width;
15597
+ let h = height ?? containerRect.height;
15598
+ if (forceEven) {
15599
+ w = Math.ceil(w / 2) * 2;
15600
+ h = Math.ceil(h / 2) * 2;
15601
+ }
15602
+ return {
15603
+ width: w,
15604
+ height: h,
15605
+ top: containerRect.top,
15606
+ left: containerRect.left
15607
+ };
15608
+ }, [width, height, containerRect, forceEven]);
15609
+ if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
15028
15610
  hasInitialSizeRef.current = true;
15029
15611
  }
15030
15612
  const canvasRef = React__namespace.useRef(null);
@@ -15043,7 +15625,7 @@ function CanvasImpl({
15043
15625
  useIsomorphicLayoutEffect(() => {
15044
15626
  effectActiveRef.current = true;
15045
15627
  const canvas = canvasRef.current;
15046
- if (containerRect.width > 0 && containerRect.height > 0 && canvas) {
15628
+ if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
15047
15629
  if (!root.current) {
15048
15630
  root.current = createRoot(canvas);
15049
15631
  notifyAlpha({
@@ -15063,21 +15645,24 @@ function CanvasImpl({
15063
15645
  async function run() {
15064
15646
  if (!effectActiveRef.current || !root.current) return;
15065
15647
  await root.current.configure({
15648
+ id,
15649
+ primaryCanvas,
15650
+ scheduler,
15066
15651
  gl,
15067
15652
  renderer,
15068
15653
  scene,
15069
15654
  events,
15070
15655
  shadows,
15071
- linear,
15072
- flat,
15073
- legacy,
15074
15656
  orthographic,
15075
15657
  frameloop,
15076
15658
  dpr,
15077
15659
  performance,
15078
15660
  raycaster,
15079
15661
  camera,
15080
- size: containerRect,
15662
+ size: effectiveSize,
15663
+ // Store size props for reset functionality
15664
+ _sizeProps: width !== void 0 || height !== void 0 ? { width, height } : null,
15665
+ forceEven,
15081
15666
  // Pass mutable reference to onPointerMissed so it's free to update
15082
15667
  onPointerMissed: (...args) => handlePointerMissed.current?.(...args),
15083
15668
  onDragOverMissed: (...args) => handleDragOverMissed.current?.(...args),
@@ -15101,7 +15686,10 @@ function CanvasImpl({
15101
15686
  });
15102
15687
  if (!effectActiveRef.current || !root.current) return;
15103
15688
  root.current.render(
15104
- /* @__PURE__ */ jsxRuntime.jsx(Bridge, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxRuntime.jsx(React__namespace.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(Block, { set: setBlock }), children: children ?? null }) }) })
15689
+ /* @__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: [
15690
+ backgroundProps && /* @__PURE__ */ jsxRuntime.jsx(Environment, { ...backgroundProps }),
15691
+ children ?? null
15692
+ ] }) }) })
15105
15693
  );
15106
15694
  }
15107
15695
  run();
@@ -15123,6 +15711,35 @@ function CanvasImpl({
15123
15711
  };
15124
15712
  }
15125
15713
  }, []);
15714
+ React__namespace.useEffect(() => {
15715
+ if (hmr === false) return;
15716
+ const canvas = canvasRef.current;
15717
+ if (!canvas) return;
15718
+ const handleHMR = () => {
15719
+ queueMicrotask(() => {
15720
+ const rootEntry = _roots.get(canvas);
15721
+ if (rootEntry?.store) {
15722
+ rootEntry.store.setState((state) => ({
15723
+ nodes: {},
15724
+ uniforms: {},
15725
+ _hmrVersion: state._hmrVersion + 1
15726
+ }));
15727
+ }
15728
+ });
15729
+ };
15730
+ if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== "undefined" && undefined) {
15731
+ const hot = undefined;
15732
+ hot.on("vite:afterUpdate", handleHMR);
15733
+ return () => hot.dispose?.(() => {
15734
+ });
15735
+ }
15736
+ if (typeof module !== "undefined" && module.hot) {
15737
+ const hot = module.hot;
15738
+ hot.addStatusHandler((status) => {
15739
+ if (status === "idle") handleHMR();
15740
+ });
15741
+ }
15742
+ }, [hmr]);
15126
15743
  const pointerEvents = eventSource ? "none" : "auto";
15127
15744
  return /* @__PURE__ */ jsxRuntime.jsx(
15128
15745
  "div",
@@ -15137,7 +15754,7 @@ function CanvasImpl({
15137
15754
  ...style
15138
15755
  },
15139
15756
  ...props,
15140
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvasRef, className: "r3f-canvas", style: { display: "block" }, children: fallback }) })
15757
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvasRef, id, className: "r3f-canvas", style: { display: "block" }, children: fallback }) })
15141
15758
  }
15142
15759
  );
15143
15760
  }
@@ -15145,6 +15762,88 @@ function Canvas(props) {
15145
15762
  return /* @__PURE__ */ jsxRuntime.jsx(itsFine.FiberProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(CanvasImpl, { ...props }) });
15146
15763
  }
15147
15764
 
15765
+ var __defProp = Object.defineProperty;
15766
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
15767
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
15768
+ var _a;
15769
+ const INTERNAL_DATA = Symbol("ScopedStore.data");
15770
+ _a = INTERNAL_DATA;
15771
+ const _ScopedStore = class _ScopedStore {
15772
+ constructor(data) {
15773
+ __publicField(this, _a);
15774
+ this[INTERNAL_DATA] = data;
15775
+ return new Proxy(this, {
15776
+ get(target, prop, receiver) {
15777
+ if (typeof prop === "string") {
15778
+ if (prop === "scope" || prop === "has" || prop === "keys") {
15779
+ return Reflect.get(target, prop, receiver);
15780
+ }
15781
+ return target[INTERNAL_DATA][prop];
15782
+ }
15783
+ return Reflect.get(target, prop, receiver);
15784
+ },
15785
+ has(target, prop) {
15786
+ return typeof prop === "string" ? prop in target[INTERNAL_DATA] : Reflect.has(target, prop);
15787
+ },
15788
+ ownKeys(target) {
15789
+ return Reflect.ownKeys(target[INTERNAL_DATA]);
15790
+ },
15791
+ getOwnPropertyDescriptor(target, prop) {
15792
+ if (typeof prop === "string" && prop in target[INTERNAL_DATA]) {
15793
+ return {
15794
+ configurable: true,
15795
+ enumerable: true,
15796
+ value: target[INTERNAL_DATA][prop]
15797
+ };
15798
+ }
15799
+ return void 0;
15800
+ }
15801
+ });
15802
+ }
15803
+ /**
15804
+ * Access a nested scope by key.
15805
+ * If the key doesn't exist or isn't a scope object, returns an empty ScopedStore.
15806
+ */
15807
+ scope(key) {
15808
+ const data = this[INTERNAL_DATA][key];
15809
+ return new _ScopedStore(
15810
+ data && typeof data === "object" ? data : {}
15811
+ );
15812
+ }
15813
+ /**
15814
+ * Check if a key exists in the store.
15815
+ */
15816
+ has(key) {
15817
+ return key in this[INTERNAL_DATA];
15818
+ }
15819
+ /**
15820
+ * Get all keys in the store.
15821
+ */
15822
+ keys() {
15823
+ return Object.keys(this[INTERNAL_DATA]);
15824
+ }
15825
+ };
15826
+ let ScopedStore = _ScopedStore;
15827
+ function createScopedStore(data) {
15828
+ return new ScopedStore(data);
15829
+ }
15830
+ function createLazyCreatorState(state) {
15831
+ let _uniforms = null;
15832
+ let _nodes = null;
15833
+ return Object.create(state, {
15834
+ uniforms: {
15835
+ get() {
15836
+ return _uniforms ?? (_uniforms = createScopedStore(state.uniforms));
15837
+ }
15838
+ },
15839
+ nodes: {
15840
+ get() {
15841
+ return _nodes ?? (_nodes = createScopedStore(state.nodes));
15842
+ }
15843
+ }
15844
+ });
15845
+ }
15846
+
15148
15847
  function addTexture(set, key, value) {
15149
15848
  set((state) => {
15150
15849
  const newMap = new Map(state.textures);
@@ -15184,6 +15883,27 @@ function createTextureOperations(set) {
15184
15883
  removeMultiple: (keys) => removeTextures(set, keys)
15185
15884
  };
15186
15885
  }
15886
+ function extractTSLValue(value) {
15887
+ if (value === null || value === void 0) return value;
15888
+ if (typeof value !== "object") return value;
15889
+ const node = value;
15890
+ if (!node.isNode) return value;
15891
+ if (node.isConstNode) {
15892
+ return node.value;
15893
+ }
15894
+ if ("value" in node) {
15895
+ let extractedValue = node.value;
15896
+ if (typeof node.traverse === "function") {
15897
+ node.traverse((n) => {
15898
+ if (n.isConstNode) {
15899
+ extractedValue = n.value;
15900
+ }
15901
+ });
15902
+ }
15903
+ return extractedValue;
15904
+ }
15905
+ return value;
15906
+ }
15187
15907
  function vectorize(inObject) {
15188
15908
  if (inObject === null || inObject === void 0) return inObject;
15189
15909
  if (typeof inObject === "string") {
@@ -15196,6 +15916,9 @@ function vectorize(inObject) {
15196
15916
  }
15197
15917
  if (typeof inObject !== "object") return inObject;
15198
15918
  const obj = inObject;
15919
+ if (obj.isNode) {
15920
+ return extractTSLValue(inObject);
15921
+ }
15199
15922
  if (obj.isVector2 || obj.isVector3 || obj.isVector4) return inObject;
15200
15923
  if (obj.isMatrix3 || obj.isMatrix4) return inObject;
15201
15924
  if (obj.isColor || obj.isEuler || obj.isQuaternion || obj.isSpherical) return inObject;
@@ -15258,21 +15981,55 @@ function useUniforms(creatorOrScope, scope) {
15258
15981
  },
15259
15982
  [store]
15260
15983
  );
15984
+ const rebuildUniforms = React.useCallback(
15985
+ (targetScope) => {
15986
+ store.setState((state) => {
15987
+ let newUniforms = {};
15988
+ if (targetScope && targetScope !== "root") {
15989
+ const { [targetScope]: _, ...rest } = state.uniforms;
15990
+ newUniforms = rest;
15991
+ } else if (targetScope === "root") {
15992
+ for (const [key, value] of Object.entries(state.uniforms)) {
15993
+ if (!isUniformNode$1(value)) newUniforms[key] = value;
15994
+ }
15995
+ }
15996
+ return { uniforms: newUniforms, _hmrVersion: state._hmrVersion + 1 };
15997
+ });
15998
+ },
15999
+ [store]
16000
+ );
15261
16001
  const inputForMemoization = React.useMemo(() => {
15262
- return is.fun(creatorOrScope) ? creatorOrScope(store.getState()) : creatorOrScope;
16002
+ let raw = creatorOrScope;
16003
+ if (is.fun(creatorOrScope)) {
16004
+ const wrappedState = createLazyCreatorState(store.getState());
16005
+ raw = creatorOrScope(wrappedState);
16006
+ }
16007
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
16008
+ const normalized = {};
16009
+ for (const [key, value] of Object.entries(raw)) {
16010
+ normalized[key] = vectorize(value);
16011
+ }
16012
+ return normalized;
16013
+ }
16014
+ return raw;
15263
16015
  }, [creatorOrScope, store]);
15264
16016
  const memoizedInput = useCompareMemoize(inputForMemoization);
16017
+ const isReader = memoizedInput === void 0 || typeof memoizedInput === "string";
16018
+ const storeUniforms = useThree((s) => s.uniforms);
16019
+ const hmrVersion = useThree((s) => s._hmrVersion);
16020
+ const readerDep = isReader ? storeUniforms : null;
16021
+ const creatorDep = isReader ? null : hmrVersion;
15265
16022
  const uniforms = React.useMemo(() => {
15266
- const state = store.getState();
15267
- const set = store.setState;
15268
16023
  if (memoizedInput === void 0) {
15269
- return state.uniforms;
16024
+ return storeUniforms;
15270
16025
  }
15271
16026
  if (typeof memoizedInput === "string") {
15272
- const scopeData = state.uniforms[memoizedInput];
16027
+ const scopeData = storeUniforms[memoizedInput];
15273
16028
  if (scopeData && !isUniformNode$1(scopeData)) return scopeData;
15274
16029
  return {};
15275
16030
  }
16031
+ const state = store.getState();
16032
+ const set = store.setState;
15276
16033
  if (typeof memoizedInput !== "object" || memoizedInput === null) {
15277
16034
  throw new Error("Invalid uniform input");
15278
16035
  }
@@ -15316,8 +16073,22 @@ function useUniforms(creatorOrScope, scope) {
15316
16073
  }
15317
16074
  }
15318
16075
  return result;
15319
- }, [store, memoizedInput, scope]);
15320
- return { ...uniforms, removeUniforms: removeUniforms2, clearUniforms };
16076
+ }, [store, memoizedInput, scope, readerDep, creatorDep]);
16077
+ return { ...uniforms, removeUniforms: removeUniforms2, clearUniforms, rebuildUniforms };
16078
+ }
16079
+ function rebuildAllUniforms(store, scope) {
16080
+ store.setState((state) => {
16081
+ let newUniforms = {};
16082
+ if (scope && scope !== "root") {
16083
+ const { [scope]: _, ...rest } = state.uniforms;
16084
+ newUniforms = rest;
16085
+ } else if (scope === "root") {
16086
+ for (const [key, value] of Object.entries(state.uniforms)) {
16087
+ if (!isUniformNode$1(value)) newUniforms[key] = value;
16088
+ }
16089
+ }
16090
+ return { uniforms: newUniforms, _hmrVersion: state._hmrVersion + 1 };
16091
+ });
15321
16092
  }
15322
16093
  function removeUniforms(set, names, scope) {
15323
16094
  set((state) => {
@@ -15382,15 +16153,17 @@ function isSameThreeType(a, b) {
15382
16153
  }
15383
16154
 
15384
16155
  const isUniformNode = (value) => value !== null && typeof value === "object" && "value" in value && "uuid" in value;
16156
+ const isTSLNode$1 = (value) => value !== null && typeof value === "object" && "uuid" in value && "nodeType" in value;
15385
16157
  function useUniform(name, value) {
15386
16158
  const store = useStore();
16159
+ const hmrVersion = useThree((s) => s._hmrVersion);
15387
16160
  return React.useMemo(() => {
15388
16161
  const state = store.getState();
15389
16162
  const set = store.setState;
15390
16163
  const existing = state.uniforms[name];
15391
16164
  if (existing && isUniformNode(existing)) {
15392
- if (value !== void 0) {
15393
- existing.value = value;
16165
+ if (value !== void 0 && !isTSLNode$1(value) && !isUniformNode(value)) {
16166
+ existing.value = typeof value === "string" ? new webgpu.Color(value) : value;
15394
16167
  }
15395
16168
  return existing;
15396
16169
  }
@@ -15399,7 +16172,24 @@ function useUniform(name, value) {
15399
16172
  `[useUniform] Uniform "${name}" not found. Create it first with: useUniform('${name}', initialValue)`
15400
16173
  );
15401
16174
  }
15402
- const node = tsl.uniform(value);
16175
+ if (isUniformNode(value)) {
16176
+ const node2 = value;
16177
+ if (typeof node2.setName === "function") {
16178
+ node2.setName(name);
16179
+ }
16180
+ set((s) => ({
16181
+ uniforms: { ...s.uniforms, [name]: node2 }
16182
+ }));
16183
+ return node2;
16184
+ }
16185
+ let node;
16186
+ if (isTSLNode$1(value)) {
16187
+ node = tsl.uniform(value);
16188
+ } else if (typeof value === "string") {
16189
+ node = tsl.uniform(new webgpu.Color(value));
16190
+ } else {
16191
+ node = tsl.uniform(value);
16192
+ }
15403
16193
  if (typeof node.setName === "function") {
15404
16194
  node.setName(name);
15405
16195
  }
@@ -15410,7 +16200,7 @@ function useUniform(name, value) {
15410
16200
  }
15411
16201
  }));
15412
16202
  return node;
15413
- }, [store, name]);
16203
+ }, [store, name, hmrVersion]);
15414
16204
  }
15415
16205
 
15416
16206
  const isTSLNode = (value) => value !== null && typeof value === "object" && ("uuid" in value || "nodeType" in value);
@@ -15451,19 +16241,46 @@ function useNodes(creatorOrScope, scope) {
15451
16241
  },
15452
16242
  [store]
15453
16243
  );
16244
+ const rebuildNodes = React.useCallback(
16245
+ (targetScope) => {
16246
+ store.setState((state) => {
16247
+ let newNodes = state.nodes;
16248
+ if (targetScope && targetScope !== "root") {
16249
+ const { [targetScope]: _, ...rest } = state.nodes;
16250
+ newNodes = rest;
16251
+ } else if (targetScope === "root") {
16252
+ newNodes = {};
16253
+ for (const [key, value] of Object.entries(state.nodes)) {
16254
+ if (!isTSLNode(value)) newNodes[key] = value;
16255
+ }
16256
+ } else {
16257
+ newNodes = {};
16258
+ }
16259
+ return { nodes: newNodes, _hmrVersion: state._hmrVersion + 1 };
16260
+ });
16261
+ },
16262
+ [store]
16263
+ );
16264
+ const isReader = creatorOrScope === void 0 || typeof creatorOrScope === "string";
16265
+ const storeNodes = useThree((s) => s.nodes);
16266
+ const hmrVersion = useThree((s) => s._hmrVersion);
16267
+ const scopeDep = typeof creatorOrScope === "string" ? creatorOrScope : scope;
16268
+ const readerDep = isReader ? storeNodes : null;
16269
+ const creatorDep = isReader ? null : hmrVersion;
15454
16270
  const nodes = React.useMemo(() => {
15455
- const state = store.getState();
15456
- const set = store.setState;
15457
16271
  if (creatorOrScope === void 0) {
15458
- return state.nodes;
16272
+ return storeNodes;
15459
16273
  }
15460
16274
  if (typeof creatorOrScope === "string") {
15461
- const scopeData = state.nodes[creatorOrScope];
16275
+ const scopeData = storeNodes[creatorOrScope];
15462
16276
  if (scopeData && !isTSLNode(scopeData)) return scopeData;
15463
16277
  return {};
15464
16278
  }
16279
+ const state = store.getState();
16280
+ const set = store.setState;
15465
16281
  const creator = creatorOrScope;
15466
- const created = creator(state);
16282
+ const wrappedState = createLazyCreatorState(state);
16283
+ const created = creator(wrappedState);
15467
16284
  const result = {};
15468
16285
  let hasNewNodes = false;
15469
16286
  if (scope) {
@@ -15472,7 +16289,7 @@ function useNodes(creatorOrScope, scope) {
15472
16289
  if (currentScope[name]) {
15473
16290
  result[name] = currentScope[name];
15474
16291
  } else {
15475
- if (typeof node.label === "function") node.setName(`${scope}.${name}`);
16292
+ node.setName?.(`${scope}.${name}`);
15476
16293
  result[name] = node;
15477
16294
  hasNewNodes = true;
15478
16295
  }
@@ -15492,7 +16309,7 @@ function useNodes(creatorOrScope, scope) {
15492
16309
  if (existing && isTSLNode(existing)) {
15493
16310
  result[name] = existing;
15494
16311
  } else {
15495
- if (typeof node.label === "function") node.setName(name);
16312
+ node.setName?.(name);
15496
16313
  result[name] = node;
15497
16314
  hasNewNodes = true;
15498
16315
  }
@@ -15501,8 +16318,25 @@ function useNodes(creatorOrScope, scope) {
15501
16318
  set((s) => ({ nodes: { ...s.nodes, ...result } }));
15502
16319
  }
15503
16320
  return result;
15504
- }, [store, typeof creatorOrScope === "string" ? creatorOrScope : scope]);
15505
- return { ...nodes, removeNodes: removeNodes2, clearNodes };
16321
+ }, [store, scopeDep, readerDep, creatorDep]);
16322
+ return { ...nodes, removeNodes: removeNodes2, clearNodes, rebuildNodes };
16323
+ }
16324
+ function rebuildAllNodes(store, scope) {
16325
+ store.setState((state) => {
16326
+ let newNodes = state.nodes;
16327
+ if (scope && scope !== "root") {
16328
+ const { [scope]: _, ...rest } = state.nodes;
16329
+ newNodes = rest;
16330
+ } else if (scope === "root") {
16331
+ newNodes = {};
16332
+ for (const [key, value] of Object.entries(state.nodes)) {
16333
+ if (!isTSLNode(value)) newNodes[key] = value;
16334
+ }
16335
+ } else {
16336
+ newNodes = {};
16337
+ }
16338
+ return { nodes: newNodes, _hmrVersion: state._hmrVersion + 1 };
16339
+ });
15506
16340
  }
15507
16341
  function removeNodes(set, names, scope) {
15508
16342
  set((state) => {
@@ -15536,10 +16370,11 @@ function useLocalNodes(creator) {
15536
16370
  const uniforms = useThree((s) => s.uniforms);
15537
16371
  const nodes = useThree((s) => s.nodes);
15538
16372
  const textures = useThree((s) => s.textures);
16373
+ const hmrVersion = useThree((s) => s._hmrVersion);
15539
16374
  return React.useMemo(() => {
15540
- const state = store.getState();
15541
- return creator(state);
15542
- }, [store, creator, uniforms, nodes, textures]);
16375
+ const wrappedState = createLazyCreatorState(store.getState());
16376
+ return creator(wrappedState);
16377
+ }, [store, creator, uniforms, nodes, textures, hmrVersion]);
15543
16378
  }
15544
16379
 
15545
16380
  function usePostProcessing(mainCB, setupCB) {
@@ -15552,6 +16387,10 @@ function usePostProcessing(mainCB, setupCB) {
15552
16387
  mainCBRef.current = mainCB;
15553
16388
  setupCBRef.current = setupCB;
15554
16389
  const [rebuildVersion, setRebuildVersion] = React.useState(0);
16390
+ React.useEffect(() => {
16391
+ callbacksRanRef.current = false;
16392
+ scenePassCacheRef.current = null;
16393
+ }, []);
15555
16394
  const clearPasses = React.useCallback(() => {
15556
16395
  store.setState({ passes: {} });
15557
16396
  }, [store]);
@@ -15635,8 +16474,15 @@ extend(THREE);
15635
16474
 
15636
16475
  exports.Block = Block;
15637
16476
  exports.Canvas = Canvas;
16477
+ exports.Environment = Environment;
16478
+ exports.EnvironmentCube = EnvironmentCube;
16479
+ exports.EnvironmentMap = EnvironmentMap;
16480
+ exports.EnvironmentPortal = EnvironmentPortal;
15638
16481
  exports.ErrorBoundary = ErrorBoundary;
16482
+ exports.FROM_REF = FROM_REF;
15639
16483
  exports.IsObject = IsObject;
16484
+ exports.ONCE = ONCE;
16485
+ exports.Portal = Portal;
15640
16486
  exports.R3F_BUILD_LEGACY = R3F_BUILD_LEGACY;
15641
16487
  exports.R3F_BUILD_WEBGPU = R3F_BUILD_WEBGPU;
15642
16488
  exports.REACT_INTERNAL_PROPS = REACT_INTERNAL_PROPS;
@@ -15662,6 +16508,7 @@ exports.createEvents = createEvents;
15662
16508
  exports.createPointerEvents = createPointerEvents;
15663
16509
  exports.createPortal = createPortal;
15664
16510
  exports.createRoot = createRoot;
16511
+ exports.createScopedStore = createScopedStore;
15665
16512
  exports.createStore = createStore;
15666
16513
  exports.createTextureOperations = createTextureOperations;
15667
16514
  exports.detach = detach;
@@ -15671,32 +16518,45 @@ exports.events = createPointerEvents;
15671
16518
  exports.extend = extend;
15672
16519
  exports.findInitialRoot = findInitialRoot;
15673
16520
  exports.flushSync = flushSync;
16521
+ exports.fromRef = fromRef;
15674
16522
  exports.getInstanceProps = getInstanceProps;
16523
+ exports.getPrimary = getPrimary;
16524
+ exports.getPrimaryIds = getPrimaryIds;
15675
16525
  exports.getRootState = getRootState;
15676
16526
  exports.getScheduler = getScheduler;
15677
16527
  exports.getUuidPrefix = getUuidPrefix;
15678
16528
  exports.hasConstructor = hasConstructor;
16529
+ exports.hasPrimary = hasPrimary;
15679
16530
  exports.invalidate = invalidate;
15680
16531
  exports.invalidateInstance = invalidateInstance;
15681
16532
  exports.is = is;
15682
16533
  exports.isColorRepresentation = isColorRepresentation;
15683
16534
  exports.isCopyable = isCopyable;
16535
+ exports.isFromRef = isFromRef;
15684
16536
  exports.isObject3D = isObject3D;
16537
+ exports.isOnce = isOnce;
15685
16538
  exports.isOrthographicCamera = isOrthographicCamera;
15686
16539
  exports.isRef = isRef;
15687
16540
  exports.isRenderer = isRenderer;
15688
16541
  exports.isTexture = isTexture;
15689
16542
  exports.isVectorLike = isVectorLike;
16543
+ exports.once = once;
15690
16544
  exports.prepare = prepare;
16545
+ exports.presetsObj = presetsObj;
16546
+ exports.rebuildAllNodes = rebuildAllNodes;
16547
+ exports.rebuildAllUniforms = rebuildAllUniforms;
15691
16548
  exports.reconciler = reconciler;
16549
+ exports.registerPrimary = registerPrimary;
15692
16550
  exports.removeInteractivity = removeInteractivity;
15693
16551
  exports.removeNodes = removeNodes;
15694
16552
  exports.removeUniforms = removeUniforms;
15695
16553
  exports.resolve = resolve;
15696
16554
  exports.unmountComponentAtNode = unmountComponentAtNode;
16555
+ exports.unregisterPrimary = unregisterPrimary;
15697
16556
  exports.updateCamera = updateCamera;
15698
16557
  exports.updateFrustum = updateFrustum;
15699
16558
  exports.useBridge = useBridge;
16559
+ exports.useEnvironment = useEnvironment;
15700
16560
  exports.useFrame = useFrame;
15701
16561
  exports.useGraph = useGraph;
15702
16562
  exports.useInstanceHandle = useInstanceHandle;
@@ -15713,3 +16573,4 @@ exports.useTextures = useTextures;
15713
16573
  exports.useThree = useThree;
15714
16574
  exports.useUniform = useUniform;
15715
16575
  exports.useUniforms = useUniforms;
16576
+ exports.waitForPrimary = waitForPrimary;