@react-three/fiber 10.0.0-alpha.0 → 10.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  import * as three_webgpu from 'three/webgpu';
2
- import { Node, ShaderNodeObject, Euler as Euler$1, Color as Color$2, ColorRepresentation as ColorRepresentation$1, Layers as Layers$1, Raycaster, Intersection as Intersection$1, Vector2 as Vector2$1, Vector3 as Vector3$1, Vector4 as Vector4$1, Quaternion as Quaternion$1, Matrix3 as Matrix3$1, Matrix4 as Matrix4$1, Object3D, Texture as Texture$1, OrthographicCamera } from 'three/webgpu';
2
+ import { RenderTarget, Node, ShaderNodeObject, Euler as Euler$1, Color as Color$2, ColorRepresentation as ColorRepresentation$1, Layers as Layers$1, Raycaster, Intersection as Intersection$1, Vector2 as Vector2$1, Vector3 as Vector3$1, Vector4 as Vector4$1, Quaternion as Quaternion$1, Matrix3 as Matrix3$1, Matrix4 as Matrix4$1, Object3D, Texture as Texture$1, Frustum, OrthographicCamera } from 'three/webgpu';
3
3
  import { Inspector } from 'three/addons/inspector/Inspector.js';
4
4
  import * as THREE$1 from 'three';
5
- import { Color as Color$1, ColorRepresentation } from 'three';
5
+ import { Color as Color$1, ColorRepresentation, RenderTargetOptions as RenderTargetOptions$1 } from 'three';
6
6
  import * as React$1 from 'react';
7
7
  import { ReactNode, Component, RefObject, JSX } from 'react';
8
8
  import { StoreApi } from 'zustand';
@@ -44,11 +44,15 @@ declare const WebGLRenderer: {
44
44
  type WebGLRendererParameters = never;
45
45
  type WebGLShadowMap = never;
46
46
 
47
+ declare const WebGLRenderTarget: any;
48
+
47
49
  var THREE = /*#__PURE__*/_mergeNamespaces({
48
50
  __proto__: null,
49
51
  Inspector: Inspector,
50
52
  R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
51
53
  R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
54
+ RenderTargetCompat: RenderTarget,
55
+ WebGLRenderTarget: WebGLRenderTarget,
52
56
  WebGLRenderer: WebGLRenderer,
53
57
  WebGLRendererParameters: WebGLRendererParameters,
54
58
  WebGLShadowMap: WebGLShadowMap
@@ -189,6 +193,14 @@ interface EventHandlers {
189
193
  onPointerCancel?: (event: ThreeEvent<PointerEvent>) => void
190
194
  onWheel?: (event: ThreeEvent<WheelEvent>) => void
191
195
  onLostPointerCapture?: (event: ThreeEvent<PointerEvent>) => void
196
+
197
+ //* Visibility Events --------------------------------
198
+ /** Fires when object enters/exits camera frustum. Receives true when in view, false when out. */
199
+ onFramed?: (inView: boolean) => void
200
+ /** Fires when object occlusion state changes (WebGPU only, requires occlusionTest=true on object) */
201
+ onOccluded?: (occluded: boolean) => void
202
+ /** Fires when combined visibility changes (frustum + occlusion + visible prop) */
203
+ onVisible?: (visible: boolean) => void
192
204
  }
193
205
 
194
206
  type FilterFunction = (items: THREE$1.Intersection[], state: RootState) => THREE$1.Intersection[]
@@ -220,6 +232,17 @@ interface EventManager<TTarget> {
220
232
  interface PointerCaptureTarget {
221
233
  intersection: Intersection
222
234
  target: Element
235
+ }
236
+
237
+ //* Visibility System Types =====================================
238
+
239
+ /** Entry in the visibility registry for tracking object visibility state */
240
+ interface VisibilityEntry {
241
+ object: THREE$1.Object3D
242
+ handlers: Pick<EventHandlers, 'onFramed' | 'onOccluded' | 'onVisible'>
243
+ lastFramedState: boolean | null
244
+ lastOccludedState: boolean | null
245
+ lastVisibleState: boolean | null
223
246
  }
224
247
 
225
248
  //* Scheduler Types (useFrame) ==============================
@@ -266,9 +289,9 @@ interface AddPhaseOptions {
266
289
  // Frame State --------------------------------
267
290
 
268
291
  /**
269
- * State passed to useFrame callbacks
292
+ * Timing-only state for independent/outside mode (no RootState)
270
293
  */
271
- interface FrameNextState extends RootState {
294
+ interface FrameTimingState {
272
295
  /** High-resolution timestamp from RAF (ms) */
273
296
  time: number
274
297
  /** Time since last frame in seconds (for legacy compatibility with THREE.Clock) */
@@ -279,9 +302,26 @@ interface FrameNextState extends RootState {
279
302
  frame: number
280
303
  }
281
304
 
305
+ /**
306
+ * State passed to useFrame callbacks (extends RootState with timing)
307
+ */
308
+ interface FrameNextState extends RootState, FrameTimingState {}
309
+
282
310
  /** Alias for FrameNextState */
283
311
  type FrameState = FrameNextState
284
312
 
313
+ // Root Options --------------------------------
314
+
315
+ /**
316
+ * Options for registerRoot
317
+ */
318
+ interface RootOptions {
319
+ /** State provider for callbacks. Optional in independent mode. */
320
+ getState?: () => any
321
+ /** Error handler for job errors. Falls back to console.error if not provided. */
322
+ onError?: (error: Error) => void
323
+ }
324
+
285
325
  // Callback Types --------------------------------
286
326
 
287
327
  /**
@@ -335,13 +375,17 @@ interface SchedulerApi {
335
375
  //* Root Management --------------------------------
336
376
 
337
377
  /** Register a root (Canvas) with the scheduler. Returns unsubscribe function. */
338
- registerRoot(id: string, getState: () => RootState): () => void
378
+ registerRoot(id: string, options?: RootOptions): () => void
339
379
  /** Unregister a root */
340
380
  unregisterRoot(id: string): void
341
381
  /** Generate a unique root ID */
342
382
  generateRootId(): string
343
383
  /** Get the number of registered roots */
344
384
  getRootCount(): number
385
+ /** Check if any root is registered and ready */
386
+ readonly isReady: boolean
387
+ /** Subscribe to root-ready event. Fires immediately if already ready. Returns unsubscribe. */
388
+ onRootReady(callback: () => void): () => void
345
389
 
346
390
  //* Job Registration --------------------------------
347
391
 
@@ -400,6 +444,8 @@ interface SchedulerApi {
400
444
  readonly isRunning: boolean
401
445
  /** Get/set the frameloop mode ('always', 'demand', 'never') */
402
446
  frameloop: Frameloop
447
+ /** Independent mode - runs without Canvas, callbacks receive timing-only state */
448
+ independent: boolean
403
449
 
404
450
  //* Manual Stepping --------------------------------
405
451
 
@@ -477,6 +523,16 @@ interface InternalState {
477
523
  initialClick: [x: number, y: number]
478
524
  initialHits: THREE$1.Object3D[]
479
525
  lastEvent: React$1.RefObject<DomEvent | null>
526
+ /** Visibility event registry (onFramed, onOccluded, onVisible) */
527
+ visibilityRegistry: Map<string, VisibilityEntry>
528
+ /** Whether occlusion queries are enabled (WebGPU only) */
529
+ occlusionEnabled: boolean
530
+ /** Reference to the invisible occlusion observer mesh */
531
+ occlusionObserver: THREE$1.Mesh | null
532
+ /** Cached occlusion results from render pass - keyed by Object3D */
533
+ occlusionCache: Map<THREE$1.Object3D, boolean | null>
534
+ /** Internal helper group for R3F system objects (occlusion observer, etc.) */
535
+ helperGroup: THREE$1.Group | null
480
536
  active: boolean
481
537
  priority: number
482
538
  frames: number
@@ -514,6 +570,10 @@ interface RootState {
514
570
 
515
571
  /** Default camera */
516
572
  camera: ThreeCamera
573
+ /** Camera frustum for visibility checks - auto-updated each frame when autoUpdateFrustum is true */
574
+ frustum: THREE$1.Frustum
575
+ /** Whether to automatically update the frustum each frame (default: true) */
576
+ autoUpdateFrustum: boolean
517
577
  /** Default scene (may be overridden in portals to point to the portal container) */
518
578
  scene: THREE$1.Scene
519
579
  /** The actual root THREE.Scene - always points to the true scene, even inside portals */
@@ -715,6 +775,14 @@ interface RenderProps<TCanvas extends HTMLCanvasElement | OffscreenCanvas$1> {
715
775
  onDragOverMissed?: (event: DragEvent) => void
716
776
  /** Response for drop events that have missed any target */
717
777
  onDropMissed?: (event: DragEvent) => void
778
+ /** Whether to automatically update the frustum each frame (default: true) */
779
+ autoUpdateFrustum?: boolean
780
+ /**
781
+ * Enable WebGPU occlusion queries for onOccluded/onVisible events.
782
+ * Auto-enabled when any object uses onOccluded or onVisible handlers.
783
+ * Only works with WebGPU renderer - WebGL will log a warning.
784
+ */
785
+ occlusion?: boolean
718
786
  }
719
787
 
720
788
  //* Reconciler Root ==============================
@@ -897,6 +965,11 @@ interface WebGLShadowConfig {
897
965
  shadows?: boolean | 'basic' | 'percentage' | 'soft' | 'variance' | Partial<THREE$1.WebGLShadowMap>
898
966
  }
899
967
 
968
+ //* RenderTarget Types ==============================
969
+
970
+
971
+ type RenderTargetOptions = RenderTargetOptions$1
972
+
900
973
  //* Global Types ==============================
901
974
 
902
975
  declare global {
@@ -915,6 +988,15 @@ declare global {
915
988
  */
916
989
  type UniformStore = Record<string, UniformNode | UniformRecord>
917
990
 
991
+ /**
992
+ * Helper to safely access a uniform node from the store.
993
+ * Use this when accessing state.uniforms to get proper typing.
994
+ * @example
995
+ * const uTime = uniforms.uTime as UniformNode<number>
996
+ * const uColor = uniforms.uColor as UniformNode<import('three/webgpu').Color>
997
+ */
998
+ type GetUniform<T = unknown> = UniformNode<T>
999
+
918
1000
  /**
919
1001
  * Acceptable input values for useUniforms - raw values that get converted to UniformNodes
920
1002
  * Supports: primitives, Three.js types, plain objects (converted to vectors), and UniformNodes
@@ -1013,6 +1095,10 @@ declare global {
1013
1095
  }
1014
1096
  }
1015
1097
 
1098
+ //* useFrameNext Types ==============================
1099
+
1100
+
1101
+
1016
1102
  //* Global Type Declarations ==============================
1017
1103
 
1018
1104
  declare global {
@@ -1104,8 +1190,8 @@ declare global {
1104
1190
  interface RootEntry {
1105
1191
  /** Unique identifier for this root */
1106
1192
  id: string
1107
- /** Function to get the root's current state */
1108
- getState: () => RootState
1193
+ /** Function to get the root's current state. Returns any to support independent mode. */
1194
+ getState: () => any
1109
1195
  /** Map of job IDs to Job objects */
1110
1196
  jobs: Map<string, Job>
1111
1197
  /** Cached sorted job list for execution order */
@@ -1297,7 +1383,9 @@ declare namespace useLoader {
1297
1383
  * - Demand mode support via invalidate()
1298
1384
  */
1299
1385
  declare class Scheduler {
1300
- private static instance;
1386
+ private static readonly INSTANCE_KEY;
1387
+ private static get instance();
1388
+ private static set instance(value);
1301
1389
  /**
1302
1390
  * Get the global scheduler instance (creates if doesn't exist).
1303
1391
  * Uses HMR data to preserve instance across hot reloads.
@@ -1323,19 +1411,25 @@ declare class Scheduler {
1323
1411
  private jobStateListeners;
1324
1412
  private pendingFrames;
1325
1413
  private _frameloop;
1414
+ private _independent;
1415
+ private errorHandler;
1416
+ private rootReadyCallbacks;
1326
1417
  get phases(): string[];
1327
1418
  get frameloop(): Frameloop;
1328
1419
  set frameloop(mode: Frameloop);
1329
1420
  get isRunning(): boolean;
1421
+ get isReady(): boolean;
1422
+ get independent(): boolean;
1423
+ set independent(value: boolean);
1330
1424
  constructor();
1331
1425
  /**
1332
1426
  * Register a root (Canvas) with the scheduler.
1333
1427
  * The first root to register starts the RAF loop (if frameloop='always').
1334
1428
  * @param {string} id - Unique identifier for this root
1335
- * @param {() => RootState} getState - Function to get the root's current state
1429
+ * @param {RootOptions} [options] - Optional configuration with getState and onError callbacks
1336
1430
  * @returns {() => void} Unsubscribe function to remove this root
1337
1431
  */
1338
- registerRoot(id: string, getState: () => RootState): () => void;
1432
+ registerRoot(id: string, options?: RootOptions): () => void;
1339
1433
  /**
1340
1434
  * Unregister a root from the scheduler.
1341
1435
  * Cleans up all job state listeners for this root's jobs.
@@ -1344,6 +1438,34 @@ declare class Scheduler {
1344
1438
  * @returns {void}
1345
1439
  */
1346
1440
  unregisterRoot(id: string): void;
1441
+ /**
1442
+ * Subscribe to be notified when a root becomes available.
1443
+ * Fires immediately if a root already exists.
1444
+ * @param {() => void} callback - Function called when first root registers
1445
+ * @returns {() => void} Unsubscribe function
1446
+ */
1447
+ onRootReady(callback: () => void): () => void;
1448
+ /**
1449
+ * Notify all registered root-ready callbacks.
1450
+ * Called when the first root registers.
1451
+ * @returns {void}
1452
+ * @private
1453
+ */
1454
+ private notifyRootReady;
1455
+ /**
1456
+ * Ensure a default root exists for independent mode.
1457
+ * Creates a minimal root with no state provider.
1458
+ * @returns {void}
1459
+ * @private
1460
+ */
1461
+ private ensureDefaultRoot;
1462
+ /**
1463
+ * Trigger error handling for job errors.
1464
+ * Uses the bound error handler if available, otherwise logs to console.
1465
+ * @param {Error} error - The error to handle
1466
+ * @returns {void}
1467
+ */
1468
+ triggerError(error: Error): void;
1347
1469
  /**
1348
1470
  * Add a named phase to the scheduler's execution order.
1349
1471
  * Marks all roots for rebuild to incorporate the new phase.
@@ -1552,7 +1674,7 @@ declare class Scheduler {
1552
1674
  /**
1553
1675
  * Execute all jobs for a single root in sorted order.
1554
1676
  * Rebuilds sorted job list if needed, then dispatches each job.
1555
- * Errors are caught and propagated to the root's error boundary.
1677
+ * Errors are caught and propagated via triggerError.
1556
1678
  * @param {RootEntry} root - The root entry to tick
1557
1679
  * @param {number} timestamp - RAF timestamp in milliseconds
1558
1680
  * @param {number} delta - Time since last frame in seconds
@@ -1615,6 +1737,11 @@ declare const getScheduler: () => Scheduler;
1615
1737
  /**
1616
1738
  * Frame hook with phase-based ordering, priority, and FPS throttling.
1617
1739
  *
1740
+ * Works both inside and outside Canvas context:
1741
+ * - Inside Canvas: Full RootState (gl, scene, camera, etc.)
1742
+ * - Outside Canvas (waiting mode): Waits for Canvas to mount, then gets full state
1743
+ * - Outside Canvas (independent mode): Fires immediately with timing-only state
1744
+ *
1618
1745
  * Returns a controls object for manual stepping, pausing, and resuming.
1619
1746
  *
1620
1747
  * @param callback - Function called each frame with (state, delta). Optional if you only need scheduler access.
@@ -1630,18 +1757,16 @@ declare const getScheduler: () => Scheduler;
1630
1757
  * useFrame((state, delta) => { ... }, { phase: 'physics' })
1631
1758
  *
1632
1759
  * @example
1633
- * // With controls
1634
- * const controls = useFrame(cb, { phase: 'physics', id: 'my-physics' })
1635
- * controls.step() // Step this job only
1636
- * controls.stepAll() // Step all jobs
1637
- * controls.pause() // Pause this job
1638
- * controls.resume() // Resume this job
1760
+ * // Outside Canvas - waits for Canvas to mount
1761
+ * function UI() {
1762
+ * useFrame((state, delta) => { syncUI(state.camera) });
1763
+ * return <button>...</button>;
1764
+ * }
1639
1765
  *
1640
1766
  * @example
1641
- * // Manual mode (frameloop='never')
1642
- * const { stepAll } = useFrame(cb)
1643
- * // In your animation controller:
1644
- * stepAll() // Advance all useFrame jobs
1767
+ * // Independent mode - no Canvas needed
1768
+ * getScheduler().independent = true;
1769
+ * useFrame((state, delta) => { updateGame(delta) });
1645
1770
  *
1646
1771
  * @example
1647
1772
  * // Scheduler-only access (no callback)
@@ -1775,6 +1900,39 @@ interface UseTexturesReturn {
1775
1900
  */
1776
1901
  declare function useTextures(): UseTexturesReturn;
1777
1902
 
1903
+ /**
1904
+ * Creates a render target compatible with the current renderer.
1905
+ *
1906
+ * - Legacy build: Returns WebGLRenderTarget
1907
+ * - WebGPU build: Returns RenderTarget
1908
+ * - Default build: Returns whichever matches the active renderer
1909
+ *
1910
+ * @param width - Target width (defaults to canvas width)
1911
+ * @param height - Target height (defaults to canvas height)
1912
+ * @param options - Three.js RenderTarget options
1913
+ *
1914
+ * @example
1915
+ * ```tsx
1916
+ * function PortalScene() {
1917
+ * const fbo = useRenderTarget(512, 512, { depthBuffer: true })
1918
+ *
1919
+ * useFrame(({ renderer, scene, camera }) => {
1920
+ * renderer.setRenderTarget(fbo)
1921
+ * renderer.render(scene, camera)
1922
+ * renderer.setRenderTarget(null)
1923
+ * })
1924
+ *
1925
+ * return (
1926
+ * <mesh>
1927
+ * <planeGeometry />
1928
+ * <meshBasicMaterial map={fbo.texture} />
1929
+ * </mesh>
1930
+ * )
1931
+ * }
1932
+ * ```
1933
+ */
1934
+ declare function useRenderTarget(width?: number, height?: number, options?: RenderTargetOptions): RenderTarget<THREE$1.Texture<unknown>>;
1935
+
1778
1936
  /**
1779
1937
  * Returns the R3F Canvas' Zustand store. Useful for [transient updates](https://github.com/pmndrs/zustand#transient-updates-for-often-occurring-state-changes).
1780
1938
  * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usestore
@@ -3309,6 +3467,26 @@ declare function getUuidPrefix(uuid: string): string;
3309
3467
  * @param size - Current viewport size
3310
3468
  */
3311
3469
  declare function updateCamera(camera: ThreeCamera, size: Size): void;
3470
+ /**
3471
+ * Updates a frustum from a camera's projection and world matrices.
3472
+ * If no target frustum is provided, creates and returns a new one.
3473
+ *
3474
+ * @param camera - Camera to extract frustum from
3475
+ * @param frustum - Optional existing frustum to update (creates new if not provided)
3476
+ * @returns The updated or newly created frustum
3477
+ *
3478
+ * @example
3479
+ * // Create new frustum
3480
+ * const frustum = updateFrustum(camera)
3481
+ *
3482
+ * // Update existing frustum (no allocation)
3483
+ * updateFrustum(camera, existingFrustum)
3484
+ *
3485
+ * // Use for visibility checks
3486
+ * if (frustum.containsPoint(point)) { ... }
3487
+ * if (frustum.intersectsObject(mesh)) { ... }
3488
+ */
3489
+ declare function updateFrustum(camera: ThreeCamera, frustum?: Frustum): Frustum;
3312
3490
 
3313
3491
  declare const is: {
3314
3492
  obj: (a: any) => boolean;
@@ -3348,50 +3526,74 @@ declare function Canvas(props: CanvasProps): react_jsx_runtime.JSX.Element;
3348
3526
 
3349
3527
  /** Creator function that returns uniform inputs (can be raw values or UniformNodes) */
3350
3528
  type UniformCreator<T extends UniformInputRecord = UniformInputRecord> = (state: RootState) => T;
3351
- declare function useUniforms(): UniformRecord;
3352
- declare function useUniforms(scope: string): UniformRecord;
3353
- declare function useUniforms<T extends UniformInputRecord>(creator: UniformCreator<T>): UniformRecord<UniformNode>;
3354
- declare function useUniforms<T extends UniformInputRecord>(creator: UniformCreator<T>, scope: string): UniformRecord<UniformNode>;
3355
- declare function useUniforms<T extends UniformInputRecord>(uniforms: T): UniformRecord<UniformNode>;
3356
- declare function useUniforms<T extends UniformInputRecord>(uniforms: T, scope: string): UniformRecord<UniformNode>;
3529
+ /** Function signature for removeUniforms util */
3530
+ type RemoveUniformsFn = (names: string | string[], scope?: string) => void;
3531
+ /** Function signature for clearUniforms util */
3532
+ type ClearUniformsFn = (scope?: string) => void;
3533
+ /** Return type with utils included */
3534
+ type UniformsWithUtils<T extends UniformRecord = UniformRecord> = T & {
3535
+ removeUniforms: RemoveUniformsFn;
3536
+ clearUniforms: ClearUniformsFn;
3537
+ };
3538
+ declare function useUniforms(): UniformsWithUtils<UniformRecord & Record<string, UniformRecord>>;
3539
+ declare function useUniforms(scope: string): UniformsWithUtils;
3540
+ declare function useUniforms<T extends UniformInputRecord>(creator: UniformCreator<T>): UniformsWithUtils<UniformRecord<UniformNode>>;
3541
+ declare function useUniforms<T extends UniformInputRecord>(creator: UniformCreator<T>, scope: string): UniformsWithUtils<UniformRecord<UniformNode>>;
3542
+ declare function useUniforms<T extends UniformInputRecord>(uniforms: T): UniformsWithUtils<UniformRecord<UniformNode>>;
3543
+ declare function useUniforms<T extends UniformInputRecord>(uniforms: T, scope: string): UniformsWithUtils<UniformRecord<UniformNode>>;
3357
3544
  /**
3358
3545
  * Remove uniforms by name from root level or a scope
3359
- * @param scope - If provided, removes from that scope. Otherwise removes from root.
3546
+ * @deprecated Use `const { removeUniforms } = useUniforms()` instead
3360
3547
  */
3361
3548
  declare function removeUniforms(set: ReturnType<typeof useStore>['setState'], names: string[], scope?: string): void;
3362
3549
  /**
3363
3550
  * Clear all uniforms from a scope (removes the entire scope object)
3551
+ * @deprecated Use `const { clearUniforms } = useUniforms()` instead
3364
3552
  */
3365
3553
  declare function clearScope(set: ReturnType<typeof useStore>['setState'], scope: string): void;
3366
3554
  /**
3367
3555
  * Clear all root-level uniforms (preserves scopes)
3556
+ * @deprecated Use `const { clearUniforms } = useUniforms()` with `clearUniforms('root')` instead
3368
3557
  */
3369
3558
  declare function clearRootUniforms(set: ReturnType<typeof useStore>['setState']): void;
3370
3559
 
3371
3560
  /** Supported uniform value types */
3372
3561
  type UniformValue = number | boolean | Vector2$1 | Vector3$1 | Vector4$1 | Color$2 | Matrix3$1 | Matrix4$1;
3562
+ /** Widen literal types to their base types (0 → number, true → boolean) */
3563
+ type Widen<T> = T extends number ? number : T extends boolean ? boolean : T;
3373
3564
  declare function useUniform<T extends UniformValue>(name: string): UniformNode<T>;
3374
- declare function useUniform<T extends UniformValue>(name: string, value: T): UniformNode<T>;
3565
+ declare function useUniform<T extends UniformValue>(name: string, value: T): UniformNode<Widen<T>>;
3375
3566
 
3376
3567
  /** TSL node type - extends Three.js Node for material compatibility */
3377
3568
  type TSLNode = Node;
3378
3569
  type NodeRecord<T extends Node = Node> = Record<string, T>;
3379
3570
  type NodeCreator<T extends NodeRecord> = (state: RootState) => T;
3380
- declare function useNodes(): NodeRecord;
3381
- declare function useNodes(scope: string): NodeRecord;
3382
- declare function useNodes<T extends NodeRecord>(creator: NodeCreator<T>): T;
3383
- declare function useNodes<T extends NodeRecord>(creator: NodeCreator<T>, scope: string): T;
3571
+ /** Function signature for removeNodes util */
3572
+ type RemoveNodesFn = (names: string | string[], scope?: string) => void;
3573
+ /** Function signature for clearNodes util */
3574
+ type ClearNodesFn = (scope?: string) => void;
3575
+ /** Return type with utils included */
3576
+ type NodesWithUtils<T extends NodeRecord = NodeRecord> = T & {
3577
+ removeNodes: RemoveNodesFn;
3578
+ clearNodes: ClearNodesFn;
3579
+ };
3580
+ declare function useNodes(): NodesWithUtils<NodeRecord & Record<string, NodeRecord>>;
3581
+ declare function useNodes(scope: string): NodesWithUtils;
3582
+ declare function useNodes<T extends NodeRecord>(creator: NodeCreator<T>): NodesWithUtils<T>;
3583
+ declare function useNodes<T extends NodeRecord>(creator: NodeCreator<T>, scope: string): NodesWithUtils<T>;
3384
3584
  /**
3385
3585
  * Remove nodes by name from root level or a scope
3386
- * @param scope - If provided, removes from that scope. Otherwise removes from root.
3586
+ * @deprecated Use `const { removeNodes } = useNodes()` instead
3387
3587
  */
3388
3588
  declare function removeNodes(set: ReturnType<typeof useStore>['setState'], names: string[], scope?: string): void;
3389
3589
  /**
3390
3590
  * Clear all nodes from a scope (removes the entire scope object)
3591
+ * @deprecated Use `const { clearNodes } = useNodes()` instead
3391
3592
  */
3392
3593
  declare function clearNodeScope(set: ReturnType<typeof useStore>['setState'], scope: string): void;
3393
3594
  /**
3394
3595
  * Clear all root-level nodes (preserves scopes)
3596
+ * @deprecated Use `const { clearNodes } = useNodes()` with `clearNodes('root')` instead
3395
3597
  */
3396
3598
  declare function clearRootNodes(set: ReturnType<typeof useStore>['setState']): void;
3397
3599
 
@@ -3415,6 +3617,12 @@ type LocalNodeCreator<T extends Record<string, unknown>> = (state: RootState) =>
3415
3617
  * const { scaled } = useLocalNodes(({ camera, nodes }) => ({
3416
3618
  * scaled: nodes.basePos.mul(camera.zoom),
3417
3619
  * }))
3620
+ *
3621
+ * // Type-safe uniform access
3622
+ * const { colorNode } = useLocalNodes(({ uniforms }) => {
3623
+ * const uValue = uniforms.myUniform as UniformNode<number>
3624
+ * return { colorNode: mix(colorA, colorB, uValue) }
3625
+ * })
3418
3626
  * ```
3419
3627
  */
3420
3628
  declare function useLocalNodes<T extends Record<string, unknown>>(creator: LocalNodeCreator<T>): T;
@@ -3466,5 +3674,5 @@ declare function createTextureOperations(set: StoreApi<RootState>['setState']):
3466
3674
  */
3467
3675
  declare function usePostProcessing(mainCB?: PostProcessingMainCallback, setupCB?: PostProcessingSetupCallback): UsePostProcessingReturn;
3468
3676
 
3469
- export { Block, Canvas, ErrorBoundary, IsObject, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, three_d as ReactThreeFiber, Scheduler, Texture, _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, clearNodeScope, clearRootNodes, clearRootUniforms, clearScope, context, createEvents, createPointerEvents, createPortal, createRoot, createStore, createTextureOperations, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, getInstanceProps, getRootState, getScheduler, getUuidPrefix, hasConstructor, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isObject3D, isOrthographicCamera, isRef, isRenderer, isTexture, isVectorLike, prepare, reconciler, removeInteractivity, removeNodes, removeUniforms, resolve, unmountComponentAtNode, updateCamera, useBridge, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useLocalNodes, useMutableCallback, useNodes, usePostProcessing, useStore, useTexture, useTextures, useThree, useUniform, useUniforms };
3470
- export type { Act, AddPhaseOptions, Args, ArgsProp, AttachFnType, AttachType, BaseRendererProps, Bridge, Camera, CameraProps, CanvasProps, Catalogue, Color, ComputeFunction, ConstructorRepresentation, DefaultGLProps, DefaultRendererProps, Disposable, DomEvent, Dpr, ElementProps, EquConfig, Euler, EventHandlers, EventManager, EventProps, Events, Extensions, FilterFunction, FrameCallback, FrameControls, FrameNextCallback, FrameNextControls, FrameNextState, FrameState, Frameloop, GLProps, GLTFLike, GlobalEffectType, GlobalRenderCallback, HostConfig, InferLoadResult, InjectState, InputLike, Instance, InstanceProps, InternalState, Intersection, IntersectionEvent, IsAllOptional, IsOptional, Layers, LoaderInstance, LoaderLike, LoaderResult, LocalNodeCreator, MappedTextureType, MathProps, MathRepresentation, MathType, MathTypes, Matrix3, Matrix4, Mutable, MutableOrReadonlyParameters, NodeCreator, NodeRecord, NonFunctionKeys, ObjectMap, OffscreenCanvas$1 as OffscreenCanvas, Overwrite, Performance, PointerCaptureTarget, Properties, Quaternion, RaycastableRepresentation, ReactProps, ReconcilerRoot, RenderCallback, RenderProps, Renderer, RendererFactory, RendererProps, Root, RootState, RootStore, SchedulerApi, SetBlock, Size, Subscription, TSLNode, TextureEntry, TextureOperations, ThreeCamera, ThreeElement, ThreeElements, ThreeElementsImpl, ThreeEvent, ThreeExports, ThreeToJSXElements, UnblockProps, UniformCreator, UniformValue, UseFrameNextOptions, UseFrameOptions, UseTextureOptions, UseTexturesReturn, Vector2, Vector3, Vector4, VectorRepresentation, Viewport, WebGLDefaultProps, WebGLProps, WebGLShadowConfig, XRManager };
3677
+ export { Block, Canvas, ErrorBoundary, IsObject, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, three_d as ReactThreeFiber, Scheduler, Texture, _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, clearNodeScope, clearRootNodes, clearRootUniforms, clearScope, context, createEvents, createPointerEvents, createPortal, createRoot, createStore, createTextureOperations, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, getInstanceProps, getRootState, getScheduler, getUuidPrefix, hasConstructor, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isObject3D, isOrthographicCamera, isRef, isRenderer, isTexture, isVectorLike, prepare, reconciler, removeInteractivity, removeNodes, removeUniforms, resolve, unmountComponentAtNode, updateCamera, updateFrustum, useBridge, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useLocalNodes, useMutableCallback, useNodes, usePostProcessing, useRenderTarget, useStore, useTexture, useTextures, useThree, useUniform, useUniforms };
3678
+ export type { Act, AddPhaseOptions, Args, ArgsProp, AttachFnType, AttachType, BaseRendererProps, Bridge, Camera, CameraProps, CanvasProps, Catalogue, ClearNodesFn, ClearUniformsFn, Color, ComputeFunction, ConstructorRepresentation, DefaultGLProps, DefaultRendererProps, Disposable, DomEvent, Dpr, ElementProps, EquConfig, Euler, EventHandlers, EventManager, EventProps, Events, Extensions, FilterFunction, FrameCallback, FrameControls, FrameNextCallback, FrameNextControls, FrameNextState, FrameState, FrameTimingState, Frameloop, GLProps, GLTFLike, GlobalEffectType, GlobalRenderCallback, HostConfig, InferLoadResult, InjectState, InputLike, Instance, InstanceProps, InternalState, Intersection, IntersectionEvent, IsAllOptional, IsOptional, Layers, LoaderInstance, LoaderLike, LoaderResult, LocalNodeCreator, MappedTextureType, MathProps, MathRepresentation, MathType, MathTypes, Matrix3, Matrix4, Mutable, MutableOrReadonlyParameters, NodeCreator, NodeRecord, NodesWithUtils, NonFunctionKeys, ObjectMap, OffscreenCanvas$1 as OffscreenCanvas, Overwrite, Performance, PointerCaptureTarget, Properties, Quaternion, RaycastableRepresentation, ReactProps, ReconcilerRoot, RemoveNodesFn, RemoveUniformsFn, RenderCallback, RenderProps, RenderTargetOptions, Renderer, RendererFactory, RendererProps, Root, RootOptions, RootState, RootStore, SchedulerApi, SetBlock, Size, Subscription, TSLNode, TextureEntry, TextureOperations, ThreeCamera, ThreeElement, ThreeElements, ThreeElementsImpl, ThreeEvent, ThreeExports, ThreeToJSXElements, UnblockProps, UniformCreator, UniformValue, UniformsWithUtils, UseFrameNextOptions, UseFrameOptions, UseTextureOptions, UseTexturesReturn, Vector2, Vector3, Vector4, VectorRepresentation, Viewport, VisibilityEntry, WebGLDefaultProps, WebGLProps, WebGLShadowConfig, XRManager };