@react-three/fiber 9.8.0 → 9.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # @react-three/fiber
2
2
 
3
+ ## 9.8.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Include native build output explicitly in published packages so workspace ignore rules cannot omit the React Native entry points.
8
+ - 77406776ae0ee61a4ca73e92082929f9a54359ab: Keep pointer capture working when an object's `args` change during a drag (#3985), and request a frame when an object is removed with `frameloop="demand"` so it disappears immediately (#3976).
9
+ - d74622ea8ed717f7212d7e19d65ff3e325508389: Fix `createPortal` memory leaks: parent subscriptions are cleaned up when a portal unmounts or is hidden by Activity (#3676), and event setters no longer retain earlier portal states (#3751). Portal state survives Activity hide/show, and parent changes made before subscribing or while hidden are applied when the subscription starts. Ports the leak fixes from v10.
10
+ - db8fdf21fa46e3b40d2791e0ea7a684d878ae404: Only register three.js constructors as JSX intrinsic elements. Non-constructor exports such as constants and `MathUtils` were previously registered with `never` props, which collapsed the props of any `React.ElementType` to `never` once `@react-three/fiber` was imported.
11
+ - bffddfaafbf9a5e1f749cb6612d6b1f0189b26a9: fix: follow devicePixelRatio changes when the canvas moves to another display or the page is zoomed.
12
+
13
+ Neither resizes the canvas, so nothing re-rendered it and the `dpr` prop stayed resolved against the old ratio: blurry on a denser display, four times the pixels on a coarser one. Roots now watch the ratio and re-resolve the prop the same way a re-render does. A fixed `dpr` is unaffected and never touches `matchMedia`, changes during an XR session apply once it ends, and environments without a working `matchMedia`, such as test setups with a partial mock, behave as before.
14
+
15
+ ## 9.8.1
16
+
17
+ ### Patch Changes
18
+
19
+ - 2bcc153b52213535e2149d70f6c01d7dcaee58a2: fix: keep a Canvas root alive while `<Activity>` hides it.
20
+
21
+ React destroys a hidden `<Activity>` tree's effects but keeps its DOM. The Canvas unmounted its root in that effect cleanup, which lost the WebGL context and disposed the scene. When the tree was shown again, the Canvas still held the unmounted root and stayed blank.
22
+
23
+ Canvas now keeps its renderer and scene state while hidden. A Canvas removed while hidden still releases its renderer.
24
+
25
+ - 138bfb0055a2534103686454c5e1f22bcdbf4537: Canvas and `root.configure()` now apply only the configuration props that changed. Runtime changes made through setters such as `setFrameloop`, or directly to `gl.shadowMap`, last through rerenders and resizes until their prop changes. The pixel ratio still follows `dpr` and the device pixel ratio on every render. Inline option objects compare by value. Changing `flat` or `linear` after creation now updates the renderer, unless `gl` sets `toneMapping` or `outputColorSpace` explicitly.
26
+
27
+ Configuration applies in call order, including calls made from a renderer factory or a store subscriber while another configuration is running.
28
+
29
+ - e0e9c2dbb5b9f1567f43ffe97205d29a4094028a: Update its-fine to 2.1.1 and bridge ancestor Activity visibility into the Canvas scene on React 19.2 and later. Hiding an Activity disconnects scene effects and useFrame subscriptions; revealing it reconnects them without resetting scene state. Keep the existing context and StrictMode bridges, and fall back to their previous behavior on React 19.0 and 19.1.
30
+ - 9ac75626b2191c65698d3bfb27c2e43d6e3c8891: fix: dispose the renderer R3F creates when its root unmounts.
31
+
32
+ Teardown only called `forceContextLoss()`, never `dispose()`. A `WebGPURenderer` built in a `gl` factory, which has no `forceContextLoss`, was never released at all: its GPU device and every allocation on it outlived the canvas. A `WebGLRenderer` lost its context while three's listener was still attached, which logged `THREE.WebGLRenderer: Context Lost.` on every unmount.
33
+
34
+ A renderer R3F builds, from its defaults, a props object or a factory, is now disposed, and then its context is lost. A renderer passed in as an instance keeps its previous teardown. Each teardown step now runs on its own, so one that throws no longer skips the rest.
35
+
36
+ - 8965ba4f05eab91c605fe0dfaaa58453c1ede7c9: Preserve an object's visibility across Activity and Suspense hiding. Visibility prop changes made while hidden take effect when the object is shown.
37
+ - 9ac75626b2191c65698d3bfb27c2e43d6e3c8891: Model root teardown with explicit open, closing, disposing, and disposed states. Allow pending unmounts to be cancelled, wait for React cleanups and queued configuration before disposing, and prevent disposed root handles from configuring or unmounting replacement roots. Complete teardown callbacks after asynchronous renderer disposal settles, and release the context even if renderer disposal fails.
38
+
3
39
  ## 9.8.0
4
40
 
5
41
  ### Minor Changes
@@ -0,0 +1,91 @@
1
+ import * as THREE from 'three';
2
+ import type { ThreeElement } from "../three-types.js";
3
+ import type { EventManager } from "./events.js";
4
+ import { type Dpr, type Frameloop, type Performance, type Renderer, type RootState, type RootStore, type Size } from "./store.js";
5
+ import { type Camera, type Properties } from "./utils.js";
6
+ interface OffscreenCanvas extends EventTarget {
7
+ }
8
+ export type DefaultGLProps = Omit<THREE.WebGLRendererParameters, 'canvas'> & {
9
+ canvas: HTMLCanvasElement | OffscreenCanvas;
10
+ };
11
+ export type GLProps = Renderer | ((defaultProps: DefaultGLProps) => Renderer) | ((defaultProps: DefaultGLProps) => Promise<Renderer>) | Partial<Properties<THREE.WebGLRenderer> | THREE.WebGLRendererParameters>;
12
+ export type CameraProps = (Camera | Partial<ThreeElement<typeof THREE.Camera> & ThreeElement<typeof THREE.PerspectiveCamera> & ThreeElement<typeof THREE.OrthographicCamera>>) & {
13
+ /** Flags the camera as manual, putting projection into your own hands */
14
+ manual?: boolean;
15
+ };
16
+ export interface RenderProps<TCanvas extends HTMLCanvasElement | OffscreenCanvas> {
17
+ /** A threejs renderer instance or props that go into the default renderer */
18
+ gl?: GLProps;
19
+ /** Dimensions to fit the renderer to. Will measure canvas dimensions if omitted */
20
+ size?: Size;
21
+ /**
22
+ * Enables shadows (by default PCFsoft). Can accept `gl.shadowMap` options for fine-tuning,
23
+ * but also strings: 'basic' | 'percentage' | 'soft' | 'variance'.
24
+ * @see https://threejs.org/docs/#api/en/renderers/WebGLRenderer.shadowMap
25
+ */
26
+ shadows?: boolean | 'basic' | 'percentage' | 'soft' | 'variance' | Partial<THREE.WebGLShadowMap>;
27
+ /**
28
+ * Disables three r139 color management.
29
+ * @see https://threejs.org/manual/#en/color-management
30
+ */
31
+ legacy?: boolean;
32
+ /** Switch off automatic sRGB encoding and gamma correction */
33
+ linear?: boolean;
34
+ /** Use `THREE.NoToneMapping` instead of `THREE.ACESFilmicToneMapping` */
35
+ flat?: boolean;
36
+ /** Creates an orthographic camera */
37
+ orthographic?: boolean;
38
+ /**
39
+ * R3F's render mode. Set to `demand` to only render on state change or `never` to take control.
40
+ * @see https://docs.pmnd.rs/react-three-fiber/advanced/scaling-performance#on-demand-rendering
41
+ */
42
+ frameloop?: Frameloop;
43
+ /**
44
+ * R3F performance options for adaptive performance.
45
+ * @see https://docs.pmnd.rs/react-three-fiber/advanced/scaling-performance#movement-regression
46
+ */
47
+ performance?: Partial<Omit<Performance, 'regress'>>;
48
+ /** Target pixel ratio. Can clamp between a range: `[min, max]` */
49
+ dpr?: Dpr;
50
+ /** Props that go into the default raycaster */
51
+ raycaster?: Partial<THREE.Raycaster>;
52
+ /** A `THREE.Scene` instance or props that go into the default scene */
53
+ scene?: THREE.Scene | Partial<THREE.Scene>;
54
+ /** A `THREE.Camera` instance or props that go into the default camera */
55
+ camera?: CameraProps;
56
+ /** An R3F event manager to manage elements' pointer events */
57
+ events?: (store: RootStore) => EventManager<HTMLElement>;
58
+ /** Callback after the canvas has rendered (but not yet committed) */
59
+ onCreated?: (state: RootState) => void;
60
+ /** Response for pointer clicks that have missed any target */
61
+ onPointerMissed?: (event: MouseEvent) => void;
62
+ }
63
+ type Canvas = DefaultGLProps['canvas'];
64
+ export type Configuration = RenderProps<Canvas>;
65
+ /** What a root has applied, so its next configuration applies only what changed */
66
+ export interface AppliedConfiguration {
67
+ /** The last configuration applied in full */
68
+ previous?: Configuration;
69
+ /** The camera prop that set the current camera */
70
+ camera?: Configuration['camera'];
71
+ }
72
+ /**
73
+ * Applies the inputs that changed since the last configuration applied in full, to a root whose
74
+ * renderer is installed. A runtime change, such as setFrameloop or an edit to gl.shadowMap, lasts
75
+ * until its input changes. The pixel ratio instead follows the device on every call. Objects and
76
+ * arrays compare shallowly, so an equal inline value is unchanged.
77
+ */
78
+ export declare function applyRootConfiguration({ store, configuration }: {
79
+ store: RootStore;
80
+ configuration: AppliedConfiguration;
81
+ }, canvas: Canvas, props: Configuration): void;
82
+ /**
83
+ * Moving to another display or zooming changes window.devicePixelRatio without resizing the canvas,
84
+ * so nothing configures the root again. Resolves the ratio the way configuration does, from the last
85
+ * applied dpr. Returns the function that stops following.
86
+ */
87
+ export declare function followDpr(root: {
88
+ store: RootStore;
89
+ configuration: AppliedConfiguration;
90
+ }): () => void;
91
+ export {};
@@ -0,0 +1,12 @@
1
+ /** Constructor registration and lookup for JSX elements. */
2
+ import type * as React from 'react';
3
+ import type { ThreeElement } from "../three-types.js";
4
+ export type ConstructorRepresentation<T = any> = new (...args: any[]) => T;
5
+ export interface Catalogue {
6
+ [name: string]: ConstructorRepresentation;
7
+ }
8
+ export declare const toPascalCase: (type: string) => string;
9
+ export declare function hasConstructor(name: string): boolean;
10
+ export declare function resolveConstructor(name: string): ConstructorRepresentation | undefined;
11
+ export declare function extend<T extends ConstructorRepresentation>(objects: T): React.ExoticComponent<ThreeElement<T>>;
12
+ export declare function extend<T extends Catalogue>(objects: T): void;
@@ -2,7 +2,8 @@ import * as THREE from 'three';
2
2
  import * as React from 'react';
3
3
  import { RootState, RenderCallback, RootStore } from "./store.js";
4
4
  import { ObjectMap } from "./utils.js";
5
- import type { Instance, ConstructorRepresentation } from "./reconciler.js";
5
+ import type { Instance } from "./reconciler.js";
6
+ import type { ConstructorRepresentation } from "./extend.js";
6
7
  /**
7
8
  * Exposes an object's {@link Instance}.
8
9
  * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useInstanceHandle
@@ -3,12 +3,17 @@ export { createEvents } from "./events.js";
3
3
  export * from "./hooks.js";
4
4
  export type { GlobalRenderCallback, GlobalEffectType } from "./loop.js";
5
5
  export { flushGlobalEffects, addEffect, addAfterEffect, addTail, invalidate, advance } from "./loop.js";
6
- export type { AttachFnType, AttachType, ConstructorRepresentation, Catalogue, Args, InstanceProps, Instance, } from "./reconciler.js";
7
- export { extend, reconciler } from "./reconciler.js";
8
- export type { ReconcilerRoot, GLProps, CameraProps, RenderProps, InjectState } from "./renderer.js";
9
- export { _roots, createRoot, unmountComponentAtNode, createPortal, flushSync } from "./renderer.js";
6
+ export type { AttachFnType, AttachType, Args, InstanceProps, Instance } from "./reconciler.js";
7
+ export type { ConstructorRepresentation, Catalogue } from "./extend.js";
8
+ export { extend } from "./extend.js";
9
+ export { reconciler, flushSync } from "./reconciler.js";
10
+ export type { GLProps, CameraProps, RenderProps } from "./configuration.js";
11
+ export type { ReconcilerRoot } from "./root.js";
12
+ export { _roots, createRoot, unmountComponentAtNode } from "./root.js";
13
+ export type { InjectState } from "./portal.js";
14
+ export { createPortal } from "./portal.js";
10
15
  export type { Subscription, Dpr, Size, Viewport, RenderCallback, Frameloop, Performance, Renderer, XRManager, RootState, RootStore, } from "./store.js";
11
16
  export { context } from "./store.js";
12
17
  export type { ObjectMap, Camera, Disposable, Act } from "./utils.js";
13
18
  export { applyProps, getRootState, dispose, act, buildGraph } from "./utils.js";
14
- export type { TrackedPromise } from "./promise.js";
19
+ export type { TrackedPromise } from "./utils/promise.js";
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ import * as THREE from 'three';
3
+ import type { ComputeFunction } from "./events.js";
4
+ import { type RootState } from "./store.js";
5
+ export type InjectState = Partial<Omit<RootState, 'events'> & {
6
+ events?: {
7
+ enabled?: boolean;
8
+ priority?: number;
9
+ compute?: ComputeFunction;
10
+ connected?: any;
11
+ };
12
+ }>;
13
+ export declare function createPortal(children: React.ReactNode, container: THREE.Object3D, state?: InjectState): React.JSX.Element;
@@ -1,24 +1,13 @@
1
1
  import * as THREE from 'three';
2
- import * as React from 'react';
3
2
  import Reconciler from '../../react-reconciler/index.js';
4
- import type { TrackedPromise } from "./promise.js";
5
3
  import { IsAllOptional } from "./utils.js";
6
4
  import type { RootStore } from "./store.js";
7
5
  import { type EventHandlers } from "./events.js";
8
- import type { ThreeElement } from "../three-types.js";
9
- export interface Root {
10
- fiber: Reconciler.FiberRoot;
11
- store: RootStore;
12
- unmountClaim: symbol | null;
13
- /** Pending only while an async renderer is being created */
14
- ready: TrackedPromise<unknown>;
15
- }
6
+ import { type ConstructorRepresentation } from "./extend.js";
7
+ export { extend } from "./extend.js";
8
+ export type { ConstructorRepresentation, Catalogue } from "./extend.js";
16
9
  export type AttachFnType<O = any> = (parent: any, self: O) => () => void;
17
10
  export type AttachType<O = any> = string | AttachFnType<O>;
18
- export type ConstructorRepresentation<T = any> = new (...args: any[]) => T;
19
- export interface Catalogue {
20
- [name: string]: ConstructorRepresentation;
21
- }
22
11
  export type Args<T> = T extends ConstructorRepresentation ? T extends typeof THREE.Color ? [r: number, g: number, b: number] | [color: THREE.ColorRepresentation] : ConstructorParameters<T> : any[];
23
12
  type ArgsProp<P> = P extends ConstructorRepresentation ? IsAllOptional<ConstructorParameters<P>> extends true ? {
24
13
  args?: Args<P>;
@@ -46,9 +35,14 @@ export interface Instance<O = any> {
46
35
  handlers: Partial<EventHandlers>;
47
36
  attach?: AttachType<O>;
48
37
  previousAttach?: any;
38
+ previousVisible: boolean | undefined;
49
39
  isHidden: boolean;
50
40
  }
51
- export declare function extend<T extends ConstructorRepresentation>(objects: T): React.ExoticComponent<ThreeElement<T>>;
52
- export declare function extend<T extends Catalogue>(objects: T): void;
53
41
  export declare const reconciler: Reconciler.Reconciler<RootStore, Instance<any>, void, Instance<any>, never, any>;
54
- export {};
42
+ /**
43
+ * Force React to flush any updates inside the provided callback synchronously and immediately.
44
+ * All the same caveats documented for react-dom's `flushSync` apply here (see https://react.dev/reference/react-dom/flushSync).
45
+ * Nevertheless, sometimes one needs to render synchronously, for example to keep DOM and 3D changes in lock-step without
46
+ * having to revert to a non-React solution. Note: this will only flush updates within the `Canvas` root.
47
+ */
48
+ export declare function flushSync<R>(fn: () => R): R;
@@ -1,91 +1,9 @@
1
- import * as React from 'react';
1
+ /** Renderer creation and resource release. Root lifetime decides when release is safe. */
2
2
  import * as THREE from 'three';
3
- import type { ThreeElement } from "../three-types.js";
4
- import { ComputeFunction, EventManager } from "./events.js";
5
- import { Root } from "./reconciler.js";
6
- import { Dpr, Frameloop, Performance, Renderer, RootState, RootStore, Size } from "./store.js";
7
- import { type Properties, Camera } from "./utils.js";
8
- import { TrackedPromise } from "./promise.js";
9
- interface OffscreenCanvas extends EventTarget {
10
- }
11
- export declare const _roots: Map<HTMLCanvasElement | OffscreenCanvas, Root>;
12
- export type DefaultGLProps = Omit<THREE.WebGLRendererParameters, 'canvas'> & {
13
- canvas: HTMLCanvasElement | OffscreenCanvas;
14
- };
15
- export type GLProps = Renderer | ((defaultProps: DefaultGLProps) => Renderer) | ((defaultProps: DefaultGLProps) => Promise<Renderer>) | Partial<Properties<THREE.WebGLRenderer> | THREE.WebGLRendererParameters>;
16
- export type CameraProps = (Camera | Partial<ThreeElement<typeof THREE.Camera> & ThreeElement<typeof THREE.PerspectiveCamera> & ThreeElement<typeof THREE.OrthographicCamera>>) & {
17
- /** Flags the camera as manual, putting projection into your own hands */
18
- manual?: boolean;
19
- };
20
- export interface RenderProps<TCanvas extends HTMLCanvasElement | OffscreenCanvas> {
21
- /** A threejs renderer instance or props that go into the default renderer */
22
- gl?: GLProps;
23
- /** Dimensions to fit the renderer to. Will measure canvas dimensions if omitted */
24
- size?: Size;
25
- /**
26
- * Enables shadows (by default PCFsoft). Can accept `gl.shadowMap` options for fine-tuning,
27
- * but also strings: 'basic' | 'percentage' | 'soft' | 'variance'.
28
- * @see https://threejs.org/docs/#api/en/renderers/WebGLRenderer.shadowMap
29
- */
30
- shadows?: boolean | 'basic' | 'percentage' | 'soft' | 'variance' | Partial<THREE.WebGLShadowMap>;
31
- /**
32
- * Disables three r139 color management.
33
- * @see https://threejs.org/manual/#en/color-management
34
- */
35
- legacy?: boolean;
36
- /** Switch off automatic sRGB encoding and gamma correction */
37
- linear?: boolean;
38
- /** Use `THREE.NoToneMapping` instead of `THREE.ACESFilmicToneMapping` */
39
- flat?: boolean;
40
- /** Creates an orthographic camera */
41
- orthographic?: boolean;
42
- /**
43
- * R3F's render mode. Set to `demand` to only render on state change or `never` to take control.
44
- * @see https://docs.pmnd.rs/react-three-fiber/advanced/scaling-performance#on-demand-rendering
45
- */
46
- frameloop?: Frameloop;
47
- /**
48
- * R3F performance options for adaptive performance.
49
- * @see https://docs.pmnd.rs/react-three-fiber/advanced/scaling-performance#movement-regression
50
- */
51
- performance?: Partial<Omit<Performance, 'regress'>>;
52
- /** Target pixel ratio. Can clamp between a range: `[min, max]` */
53
- dpr?: Dpr;
54
- /** Props that go into the default raycaster */
55
- raycaster?: Partial<THREE.Raycaster>;
56
- /** A `THREE.Scene` instance or props that go into the default scene */
57
- scene?: THREE.Scene | Partial<THREE.Scene>;
58
- /** A `THREE.Camera` instance or props that go into the default camera */
59
- camera?: CameraProps;
60
- /** An R3F event manager to manage elements' pointer events */
61
- events?: (store: RootStore) => EventManager<HTMLElement>;
62
- /** Callback after the canvas has rendered (but not yet committed) */
63
- onCreated?: (state: RootState) => void;
64
- /** Response for pointer clicks that have missed any target */
65
- onPointerMissed?: (event: MouseEvent) => void;
66
- }
67
- export interface ReconcilerRoot<TCanvas extends HTMLCanvasElement | OffscreenCanvas> {
68
- ready: TrackedPromise<unknown>;
69
- configure: (config?: RenderProps<TCanvas>) => TrackedPromise<ReconcilerRoot<TCanvas>>;
70
- render: (element: React.ReactNode) => RootStore;
71
- unmount: () => void;
72
- }
73
- export declare function createRoot<TCanvas extends HTMLCanvasElement | OffscreenCanvas>(canvas: TCanvas): ReconcilerRoot<TCanvas>;
74
- export declare function unmountComponentAtNode<TCanvas extends HTMLCanvasElement | OffscreenCanvas>(canvas: TCanvas, callback?: (canvas: TCanvas) => void): void;
75
- export type InjectState = Partial<Omit<RootState, 'events'> & {
76
- events?: {
77
- enabled?: boolean;
78
- priority?: number;
79
- compute?: ComputeFunction;
80
- connected?: any;
81
- };
82
- }>;
83
- export declare function createPortal(children: React.ReactNode, container: THREE.Object3D, state?: InjectState): React.JSX.Element;
84
- /**
85
- * Force React to flush any updates inside the provided callback synchronously and immediately.
86
- * All the same caveats documented for react-dom's `flushSync` apply here (see https://react.dev/reference/react-dom/flushSync).
87
- * Nevertheless, sometimes one needs to render synchronously, for example to keep DOM and 3D changes in lock-step without
88
- * having to revert to a non-React solution. Note: this will only flush updates within the `Canvas` root.
89
- */
90
- export declare function flushSync<R>(fn: () => R): R;
91
- export {};
3
+ import type { DefaultGLProps, GLProps } from "./configuration.js";
4
+ import type { Renderer } from "./store.js";
5
+ export declare const isRenderer: (def: any) => boolean;
6
+ /** The renderer to configure, or a promise for one from an async factory */
7
+ export declare function createRenderer(canvas: DefaultGLProps['canvas'], gl?: GLProps): Renderer | PromiseLike<Renderer>;
8
+ /** Owned renderers are disposed. Caller-provided renderers release caches and their context. */
9
+ export declare function releaseRenderer(gl: THREE.WebGLRenderer | undefined, owned: boolean): void | Promise<void>;
@@ -0,0 +1,37 @@
1
+ import * as React from 'react';
2
+ import type Reconciler from '../../react-reconciler/index.js';
3
+ import { type AppliedConfiguration, type RenderProps } from "./configuration.js";
4
+ import { type TrackedPromise } from "./utils/promise.js";
5
+ import { type RootStore } from "./store.js";
6
+ interface OffscreenCanvas extends EventTarget {
7
+ }
8
+ export interface Root {
9
+ fiber: Reconciler.FiberRoot;
10
+ store: RootStore;
11
+ state: RootStateMachine;
12
+ /** Settles once all accepted configuration has been applied */
13
+ ready: TrackedPromise<unknown>;
14
+ configuration: AppliedConfiguration;
15
+ /** Whether R3F built `gl` (from defaults, props or a factory) and so disposes it on unmount */
16
+ ownsRenderer: boolean;
17
+ /** Stops following devicePixelRatio changes */
18
+ unwatchDpr?: () => void;
19
+ }
20
+ export declare const _roots: Map<HTMLCanvasElement | OffscreenCanvas, Root>;
21
+ export type RootStateMachine = {
22
+ status: 'open';
23
+ } | {
24
+ status: 'closing';
25
+ token: symbol;
26
+ } | {
27
+ status: 'disposed';
28
+ };
29
+ export interface ReconcilerRoot<TCanvas extends HTMLCanvasElement | OffscreenCanvas> {
30
+ ready: TrackedPromise<unknown>;
31
+ configure: (config?: RenderProps<TCanvas>) => TrackedPromise<ReconcilerRoot<TCanvas>>;
32
+ render: (element: React.ReactNode) => RootStore;
33
+ unmount: () => void;
34
+ }
35
+ export declare function createRoot<TCanvas extends HTMLCanvasElement | OffscreenCanvas>(canvas: TCanvas): ReconcilerRoot<TCanvas>;
36
+ export declare function unmountComponentAtNode<TCanvas extends HTMLCanvasElement | OffscreenCanvas>(canvas: TCanvas, callback?: (canvas: TCanvas) => void): void;
37
+ export {};
@@ -49,7 +49,7 @@ export interface Performance {
49
49
  export interface Renderer {
50
50
  render: (scene: THREE.Scene, camera: THREE.Camera) => any;
51
51
  }
52
- export declare const isRenderer: (def: any) => boolean;
52
+ export { isRenderer } from "./renderer.js";
53
53
  export interface InternalState {
54
54
  interaction: THREE.Object3D[];
55
55
  hovered: Map<string, ThreeEvent<DomEvent>>;
@@ -1,4 +1,4 @@
1
- export declare const isPromiseLike: (value: unknown) => value is PromiseLike<unknown>;
1
+ export declare const isPromiseLike: <T>(value: T | PromiseLike<T>) => value is PromiseLike<T>;
2
2
  /** A promise tagged with its state, the protocol React's `use` reads */
3
3
  export type TrackedPromise<T> = Promise<T> & ({
4
4
  status: 'pending';
@@ -11,5 +11,9 @@ export type TrackedPromise<T> = Promise<T> & ({
11
11
  });
12
12
  export declare const fulfilled: <T>(value: T) => TrackedPromise<T>;
13
13
  export declare const rejected: <T>(reason: unknown) => TrackedPromise<T>;
14
- /** Tags `promise` in place once it settles. */
15
- export declare const tracked: <T>(promise: PromiseLike<T>) => TrackedPromise<T>;
14
+ /** A pending promise, settled once from outside. Its `status` updates the moment it settles */
15
+ export declare const deferred: <T>() => {
16
+ promise: TrackedPromise<T>;
17
+ resolve: (_value: T) => void;
18
+ reject: (_reason: unknown) => void;
19
+ };
@@ -0,0 +1,184 @@
1
+ import * as React from 'react';
2
+ export type Act = <T = any>(cb: () => Promise<T>) => Promise<T>;
3
+ /**
4
+ * Safely flush async effects when testing, simulating a legacy root.
5
+ * @deprecated Import from React instead. import { act } from 'react'
6
+ */
7
+ export declare const act: Act;
8
+ /**
9
+ * An SSR-friendly useLayoutEffect.
10
+ *
11
+ * React currently throws a warning when using useLayoutEffect on the server.
12
+ * To get around it, we can conditionally useEffect on the server (no-op) and
13
+ * useLayoutEffect elsewhere.
14
+ *
15
+ * @see https://github.com/facebook/react/issues/14927
16
+ */
17
+ export declare const useIsomorphicLayoutEffect: typeof React.useLayoutEffect;
18
+ export declare function useMutableCallback<T>(fn: T): React.RefObject<T>;
19
+ /** Waits for a promise in a null subtree, re-rendering the caller once it settles either way. */
20
+ export declare function useGate(): [gate: React.ReactNode, waitFor: (promise: PromiseLike<unknown>) => void];
21
+ export type Bridge = React.FC<{
22
+ children?: React.ReactNode;
23
+ }>;
24
+ /**
25
+ * Bridges Context, StrictMode, and Activity visibility from a primary renderer.
26
+ */
27
+ export declare function useBridge(): Bridge;
28
+ export type SetBlock = false | Promise<null> | null;
29
+ export type UnblockProps = {
30
+ set: React.Dispatch<React.SetStateAction<SetBlock>>;
31
+ children: React.ReactNode;
32
+ };
33
+ export declare function Block({ set }: Omit<UnblockProps, 'children'>): null;
34
+ export declare const ErrorBoundary: {
35
+ new (props: {
36
+ set: React.Dispatch<Error | undefined>;
37
+ children: React.ReactNode;
38
+ }): {
39
+ state: {
40
+ error: boolean;
41
+ };
42
+ componentDidCatch(err: Error): void;
43
+ render(): React.ReactNode;
44
+ context: unknown;
45
+ setState<K extends "error">(state: {
46
+ error: boolean;
47
+ } | ((prevState: Readonly<{
48
+ error: boolean;
49
+ }>, props: Readonly<{
50
+ set: React.Dispatch<Error | undefined>;
51
+ children: React.ReactNode;
52
+ }>) => {
53
+ error: boolean;
54
+ } | Pick<{
55
+ error: boolean;
56
+ }, K> | null) | Pick<{
57
+ error: boolean;
58
+ }, K> | null, callback?: (() => void) | undefined): void;
59
+ forceUpdate(callback?: (() => void) | undefined): void;
60
+ readonly props: Readonly<{
61
+ set: React.Dispatch<Error | undefined>;
62
+ children: React.ReactNode;
63
+ }>;
64
+ componentDidMount?(): void;
65
+ shouldComponentUpdate?(nextProps: Readonly<{
66
+ set: React.Dispatch<Error | undefined>;
67
+ children: React.ReactNode;
68
+ }>, nextState: Readonly<{
69
+ error: boolean;
70
+ }>, nextContext: any): boolean;
71
+ componentWillUnmount?(): void;
72
+ getSnapshotBeforeUpdate?(prevProps: Readonly<{
73
+ set: React.Dispatch<Error | undefined>;
74
+ children: React.ReactNode;
75
+ }>, prevState: Readonly<{
76
+ error: boolean;
77
+ }>): any;
78
+ componentDidUpdate?(prevProps: Readonly<{
79
+ set: React.Dispatch<Error | undefined>;
80
+ children: React.ReactNode;
81
+ }>, prevState: Readonly<{
82
+ error: boolean;
83
+ }>, snapshot?: any): void;
84
+ componentWillMount?(): void;
85
+ UNSAFE_componentWillMount?(): void;
86
+ componentWillReceiveProps?(nextProps: Readonly<{
87
+ set: React.Dispatch<Error | undefined>;
88
+ children: React.ReactNode;
89
+ }>, nextContext: any): void;
90
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<{
91
+ set: React.Dispatch<Error | undefined>;
92
+ children: React.ReactNode;
93
+ }>, nextContext: any): void;
94
+ componentWillUpdate?(nextProps: Readonly<{
95
+ set: React.Dispatch<Error | undefined>;
96
+ children: React.ReactNode;
97
+ }>, nextState: Readonly<{
98
+ error: boolean;
99
+ }>, nextContext: any): void;
100
+ UNSAFE_componentWillUpdate?(nextProps: Readonly<{
101
+ set: React.Dispatch<Error | undefined>;
102
+ children: React.ReactNode;
103
+ }>, nextState: Readonly<{
104
+ error: boolean;
105
+ }>, nextContext: any): void;
106
+ };
107
+ new (props: {
108
+ set: React.Dispatch<Error | undefined>;
109
+ children: React.ReactNode;
110
+ }, context: any): {
111
+ state: {
112
+ error: boolean;
113
+ };
114
+ componentDidCatch(err: Error): void;
115
+ render(): React.ReactNode;
116
+ context: unknown;
117
+ setState<K extends "error">(state: {
118
+ error: boolean;
119
+ } | ((prevState: Readonly<{
120
+ error: boolean;
121
+ }>, props: Readonly<{
122
+ set: React.Dispatch<Error | undefined>;
123
+ children: React.ReactNode;
124
+ }>) => {
125
+ error: boolean;
126
+ } | Pick<{
127
+ error: boolean;
128
+ }, K> | null) | Pick<{
129
+ error: boolean;
130
+ }, K> | null, callback?: (() => void) | undefined): void;
131
+ forceUpdate(callback?: (() => void) | undefined): void;
132
+ readonly props: Readonly<{
133
+ set: React.Dispatch<Error | undefined>;
134
+ children: React.ReactNode;
135
+ }>;
136
+ componentDidMount?(): void;
137
+ shouldComponentUpdate?(nextProps: Readonly<{
138
+ set: React.Dispatch<Error | undefined>;
139
+ children: React.ReactNode;
140
+ }>, nextState: Readonly<{
141
+ error: boolean;
142
+ }>, nextContext: any): boolean;
143
+ componentWillUnmount?(): void;
144
+ getSnapshotBeforeUpdate?(prevProps: Readonly<{
145
+ set: React.Dispatch<Error | undefined>;
146
+ children: React.ReactNode;
147
+ }>, prevState: Readonly<{
148
+ error: boolean;
149
+ }>): any;
150
+ componentDidUpdate?(prevProps: Readonly<{
151
+ set: React.Dispatch<Error | undefined>;
152
+ children: React.ReactNode;
153
+ }>, prevState: Readonly<{
154
+ error: boolean;
155
+ }>, snapshot?: any): void;
156
+ componentWillMount?(): void;
157
+ UNSAFE_componentWillMount?(): void;
158
+ componentWillReceiveProps?(nextProps: Readonly<{
159
+ set: React.Dispatch<Error | undefined>;
160
+ children: React.ReactNode;
161
+ }>, nextContext: any): void;
162
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<{
163
+ set: React.Dispatch<Error | undefined>;
164
+ children: React.ReactNode;
165
+ }>, nextContext: any): void;
166
+ componentWillUpdate?(nextProps: Readonly<{
167
+ set: React.Dispatch<Error | undefined>;
168
+ children: React.ReactNode;
169
+ }>, nextState: Readonly<{
170
+ error: boolean;
171
+ }>, nextContext: any): void;
172
+ UNSAFE_componentWillUpdate?(nextProps: Readonly<{
173
+ set: React.Dispatch<Error | undefined>;
174
+ children: React.ReactNode;
175
+ }>, nextState: Readonly<{
176
+ error: boolean;
177
+ }>, nextContext: any): void;
178
+ };
179
+ getDerivedStateFromError: () => {
180
+ error: boolean;
181
+ };
182
+ contextType?: React.Context<any> | undefined;
183
+ propTypes?: any;
184
+ };