@jamesyong42/infinite-canvas 1.2.0 → 1.4.0
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/README.md +65 -0
- package/dist/advanced.cjs +61 -24
- package/dist/advanced.cjs.map +1 -1
- package/dist/advanced.d.cts +180 -64
- package/dist/advanced.d.cts.map +1 -1
- package/dist/advanced.d.mts +180 -64
- package/dist/advanced.d.mts.map +1 -1
- package/dist/advanced.mjs +29 -12
- package/dist/advanced.mjs.map +1 -1
- package/dist/devtools.cjs +22 -22
- package/dist/devtools.cjs.map +1 -1
- package/dist/devtools.d.cts +2 -2
- package/dist/devtools.d.cts.map +1 -1
- package/dist/devtools.d.mts +2 -2
- package/dist/devtools.d.mts.map +1 -1
- package/dist/devtools.mjs +2 -2
- package/dist/devtools.mjs.map +1 -1
- package/dist/{hooks-BwY7rRHg.mjs → ecs-3kimUV5Z.mjs} +238 -74
- package/dist/ecs-3kimUV5Z.mjs.map +1 -0
- package/dist/{hooks-DHShH86C.cjs → ecs-B4QrqfvQ.cjs} +320 -108
- package/dist/ecs-B4QrqfvQ.cjs.map +1 -0
- package/dist/hooks-CtP02JNt.cjs +3762 -0
- package/dist/hooks-CtP02JNt.cjs.map +1 -0
- package/dist/hooks-gsQDDE56.mjs +3494 -0
- package/dist/hooks-gsQDDE56.mjs.map +1 -0
- package/dist/index-3GY7T8JM.d.mts +480 -0
- package/dist/index-3GY7T8JM.d.mts.map +1 -0
- package/dist/index-B7B1tRPl.d.cts +480 -0
- package/dist/index-B7B1tRPl.d.cts.map +1 -0
- package/dist/index-DSdbSQ_t.d.cts +1451 -0
- package/dist/index-DSdbSQ_t.d.cts.map +1 -0
- package/dist/index-Dj9odADH.d.mts +1451 -0
- package/dist/index-Dj9odADH.d.mts.map +1 -0
- package/dist/index.cjs +3901 -643
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +315 -138
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +315 -138
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3803 -571
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/SelectionRenderer-CR2PBQwx.d.cts +0 -105
- package/dist/SelectionRenderer-CR2PBQwx.d.cts.map +0 -1
- package/dist/SelectionRenderer-DlsBstAq.d.mts +0 -105
- package/dist/SelectionRenderer-DlsBstAq.d.mts.map +0 -1
- package/dist/WebGLWidgetLayer-BBMuwzHq.cjs +0 -3560
- package/dist/WebGLWidgetLayer-BBMuwzHq.cjs.map +0 -1
- package/dist/WebGLWidgetLayer-C3p1tnpm.mjs +0 -3375
- package/dist/WebGLWidgetLayer-C3p1tnpm.mjs.map +0 -1
- package/dist/engine-BfbvWXSk.d.mts +0 -982
- package/dist/engine-BfbvWXSk.d.mts.map +0 -1
- package/dist/engine-CCjuFMC-.d.cts +0 -982
- package/dist/engine-CCjuFMC-.d.cts.map +0 -1
- package/dist/hooks-BwY7rRHg.mjs.map +0 -1
- package/dist/hooks-DHShH86C.cjs.map +0 -1
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
import { S as DomWidgetProps, T as Widget, r as LayoutEngine, w as R3FWidgetProps } from "./index-Dj9odADH.mjs";
|
|
2
|
+
import * as _$_jamesyong42_reactive_ecs0 from "@jamesyong42/reactive-ecs";
|
|
3
|
+
import { EntityId } from "@jamesyong42/reactive-ecs";
|
|
4
|
+
import * as _$react from "react";
|
|
5
|
+
import * as THREE from "three";
|
|
6
|
+
import { BufferGeometry, Material, OrthographicCamera, Scene, ShaderMaterial, Texture, Vector2, Vector3, WebGLRenderTarget } from "three";
|
|
7
|
+
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
8
|
+
|
|
9
|
+
//#region src/react/context/container-ref-context.d.ts
|
|
10
|
+
declare const ContainerRefProvider: _$react.Provider<_$react.RefObject<HTMLDivElement | null> | null>;
|
|
11
|
+
declare function useContainerRef(): React.RefObject<HTMLDivElement | null> | null;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/react/context/engine-context.d.ts
|
|
14
|
+
declare const EngineProvider: _$react.Provider<LayoutEngine<Widget> | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Returns the LayoutEngine instance from the nearest InfiniteCanvas context.
|
|
17
|
+
* Throws if used outside an InfiniteCanvas provider.
|
|
18
|
+
*/
|
|
19
|
+
declare function useLayoutEngine(): LayoutEngine;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/react/context/widget-resolver-context.d.ts
|
|
22
|
+
/**
|
|
23
|
+
* Discriminated resolution of a widget by type. The surface determines which
|
|
24
|
+
* layer renders the component and with what prop shape.
|
|
25
|
+
*/
|
|
26
|
+
type ResolvedWidget = {
|
|
27
|
+
surface: 'dom';
|
|
28
|
+
component: React.ComponentType<DomWidgetProps>;
|
|
29
|
+
} | {
|
|
30
|
+
surface: 'webgl';
|
|
31
|
+
component: React.ComponentType<R3FWidgetProps>;
|
|
32
|
+
};
|
|
33
|
+
type WidgetResolver = (entityId: EntityId, widgetType: string) => ResolvedWidget | null;
|
|
34
|
+
declare const WidgetResolverProvider: _$react.Provider<WidgetResolver | null>;
|
|
35
|
+
declare function useWidgetResolver(): WidgetResolver | null;
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/webgl/renderers/GridRenderer.d.ts
|
|
38
|
+
interface GridConfig {
|
|
39
|
+
/** World-unit spacings for up to 3 grid levels [fine, medium, coarse]. */
|
|
40
|
+
spacings: [number, number, number];
|
|
41
|
+
/** Dot RGB color as [r, g, b] in 0–1 range. */
|
|
42
|
+
dotColor: [number, number, number];
|
|
43
|
+
/** Base dot opacity multiplier (0–1). */
|
|
44
|
+
dotAlpha: number;
|
|
45
|
+
/** CSS-pixel range where a grid level fades in: [start, end]. */
|
|
46
|
+
fadeIn: [number, number];
|
|
47
|
+
/** CSS-pixel range where a grid level fades out: [start, end]. */
|
|
48
|
+
fadeOut: [number, number];
|
|
49
|
+
/** Dot radius range in CSS pixels [min, max]. Scaled by DPR internally. */
|
|
50
|
+
dotRadius: [number, number];
|
|
51
|
+
/** Per-level opacity weight: level i gets (base + i * step). */
|
|
52
|
+
levelWeight: [number, number];
|
|
53
|
+
}
|
|
54
|
+
declare const DEFAULT_GRID_CONFIG: GridConfig;
|
|
55
|
+
/**
|
|
56
|
+
* Draws the infinite dot-grid background into a THREE.WebGLRenderer.
|
|
57
|
+
* The renderer is owned by the parent (see {@link WebGLManager}) — this class
|
|
58
|
+
* only contributes a scene, camera, and shader material.
|
|
59
|
+
*/
|
|
60
|
+
declare class GridRenderer {
|
|
61
|
+
private scene;
|
|
62
|
+
private camera;
|
|
63
|
+
private material;
|
|
64
|
+
private mesh;
|
|
65
|
+
constructor();
|
|
66
|
+
/** Apply a (partial) grid config. Only provided fields are updated. */
|
|
67
|
+
setConfig(config: Partial<GridConfig>): void;
|
|
68
|
+
setSize(width: number, height: number, dpr?: number): void;
|
|
69
|
+
render(renderer: THREE.WebGLRenderer, cameraX: number, cameraY: number, zoom: number): void;
|
|
70
|
+
dispose(): void;
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/webgl/renderers/SelectionRenderer.d.ts
|
|
74
|
+
interface SelectionConfig {
|
|
75
|
+
/** Selection outline color [r,g,b] 0-1. Default: Figma blue. */
|
|
76
|
+
outlineColor: [number, number, number];
|
|
77
|
+
/** Selection outline width in screen px. */
|
|
78
|
+
outlineWidth: number;
|
|
79
|
+
/** Hover outline color [r,g,b] 0-1. */
|
|
80
|
+
hoverColor: [number, number, number];
|
|
81
|
+
/** Hover outline width in screen px. */
|
|
82
|
+
hoverWidth: number;
|
|
83
|
+
/** Handle size in screen px. */
|
|
84
|
+
handleSize: number;
|
|
85
|
+
/** Handle fill color [r,g,b] 0-1 (white). */
|
|
86
|
+
handleFill: [number, number, number];
|
|
87
|
+
/** Handle border color [r,g,b] 0-1 (same as outline). */
|
|
88
|
+
handleBorder: [number, number, number];
|
|
89
|
+
/** Handle border width in screen px. */
|
|
90
|
+
handleBorderWidth: number;
|
|
91
|
+
/** Group bbox dash length in screen px (0 = solid). */
|
|
92
|
+
groupDash: number;
|
|
93
|
+
}
|
|
94
|
+
declare const DEFAULT_SELECTION_CONFIG: SelectionConfig;
|
|
95
|
+
interface SelectionBounds {
|
|
96
|
+
x: number;
|
|
97
|
+
y: number;
|
|
98
|
+
width: number;
|
|
99
|
+
height: number;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Draws selection outlines, 8 resize handles, group-bbox, and the hover
|
|
103
|
+
* outline in a single SDF-based shader pass. Snap guides and equal-
|
|
104
|
+
* spacing indicators are a separate concern — see {@link SnapGuideRenderer}.
|
|
105
|
+
*
|
|
106
|
+
* The `THREE.WebGLRenderer` is owned by the parent ({@link WebGLManager})
|
|
107
|
+
* and passed to each render call so grid + selection can share a single
|
|
108
|
+
* GL context and accumulate `renderer.info` counters for the same tick.
|
|
109
|
+
*/
|
|
110
|
+
declare class SelectionRenderer {
|
|
111
|
+
private material;
|
|
112
|
+
private mesh;
|
|
113
|
+
private scene;
|
|
114
|
+
private camera;
|
|
115
|
+
constructor();
|
|
116
|
+
setConfig(config: Partial<SelectionConfig>): void;
|
|
117
|
+
setSize(resolution: THREE.Vector2, dpr: number): void;
|
|
118
|
+
render(renderer: THREE.WebGLRenderer, cameraX: number, cameraY: number, zoom: number, selected: SelectionBounds[], hovered: SelectionBounds | null): void;
|
|
119
|
+
dispose(): void;
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region src/webgl/renderers/SnapGuideRenderer.d.ts
|
|
123
|
+
interface SnapGuideConfig {
|
|
124
|
+
/** Guide line + spacing indicator color [r,g,b] 0-1. */
|
|
125
|
+
color: [number, number, number];
|
|
126
|
+
/** Line width in world pixels (constant across zoom). */
|
|
127
|
+
lineWidth: number;
|
|
128
|
+
/** Guide alpha (full-canvas alignment lines). */
|
|
129
|
+
guideAlpha: number;
|
|
130
|
+
/** Equal-spacing indicator alpha. */
|
|
131
|
+
spacingAlpha: number;
|
|
132
|
+
}
|
|
133
|
+
declare const DEFAULT_SNAP_GUIDE_CONFIG: SnapGuideConfig;
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/r3f/compositor/ResourceRegistry.d.ts
|
|
136
|
+
/**
|
|
137
|
+
* Archetype-keyed cache of GPU resources shared across per-widget scenes
|
|
138
|
+
* (RFC-002 § Three.js resource sharing).
|
|
139
|
+
*
|
|
140
|
+
* Geometries, materials, and textures returned by `acquire*` are reference
|
|
141
|
+
* counted. The registry disposes the underlying resource only after every
|
|
142
|
+
* holder has called the matching `release*` — so 100 widgets of the same
|
|
143
|
+
* card archetype share one geometry instance and one set of material
|
|
144
|
+
* uniforms, rather than allocating 100 copies.
|
|
145
|
+
*/
|
|
146
|
+
declare class ResourceRegistry {
|
|
147
|
+
private geometries;
|
|
148
|
+
private materials;
|
|
149
|
+
private textures;
|
|
150
|
+
private disposed;
|
|
151
|
+
acquireGeometry<T extends BufferGeometry>(key: string, factory: () => T): T;
|
|
152
|
+
releaseGeometry(key: string): void;
|
|
153
|
+
acquireMaterial<T extends Material>(key: string, factory: () => T): T;
|
|
154
|
+
releaseMaterial(key: string): void;
|
|
155
|
+
acquireTexture<T extends Texture>(key: string, factory: () => T): T;
|
|
156
|
+
releaseTexture(key: string): void;
|
|
157
|
+
/** Number of distinct shared geometries currently held. */
|
|
158
|
+
geometryCount(): number;
|
|
159
|
+
/** Number of distinct shared materials currently held. */
|
|
160
|
+
materialCount(): number;
|
|
161
|
+
/** Number of distinct shared textures currently held. */
|
|
162
|
+
textureCount(): number;
|
|
163
|
+
/**
|
|
164
|
+
* Estimated GPU bytes for shared geometry attribute buffers. Best-effort —
|
|
165
|
+
* actual GPU footprint depends on driver alignment, but this is a useful
|
|
166
|
+
* relative metric for the profiler.
|
|
167
|
+
*/
|
|
168
|
+
geometryBytes(): number;
|
|
169
|
+
/** Dispose every resource and clear the registry. */
|
|
170
|
+
dispose(): void;
|
|
171
|
+
/** True after `dispose()` — callers should re-create the registry instead of using it. */
|
|
172
|
+
isDisposed(): boolean;
|
|
173
|
+
private release;
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
176
|
+
//#region src/r3f/compositor/WidgetRenderTargetPool.d.ts
|
|
177
|
+
/** Snapshot returned by {@link WidgetRenderTargetPool.entries}. */
|
|
178
|
+
type PoolEntryInfo = {
|
|
179
|
+
entityId: EntityId;
|
|
180
|
+
bytes: number;
|
|
181
|
+
lastUsedMs: number;
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Allocates one persistent `WebGLRenderTarget` per R3F widget entity. Used
|
|
185
|
+
* by the compositor (RFC-002 Phase 4) so each widget paints into its own
|
|
186
|
+
* texture instead of into the main canvas backbuffer.
|
|
187
|
+
*
|
|
188
|
+
* Acquire returns an existing FBO if its pixel resolution matches the
|
|
189
|
+
* request; otherwise the old FBO is disposed and a new one created (sized
|
|
190
|
+
* to the new resolution). Eviction under memory pressure is Phase 6 — this
|
|
191
|
+
* pool grows monotonically until widgets are released.
|
|
192
|
+
*/
|
|
193
|
+
declare class WidgetRenderTargetPool {
|
|
194
|
+
private entries;
|
|
195
|
+
private totalBytes;
|
|
196
|
+
private disposed;
|
|
197
|
+
/**
|
|
198
|
+
* Get or create an FBO for `entityId` at the requested logical size and
|
|
199
|
+
* device pixel ratio. If an FBO already exists at the same pixel
|
|
200
|
+
* dimensions, returns it unchanged.
|
|
201
|
+
*/
|
|
202
|
+
acquire(entityId: EntityId, width: number, height: number, dpr: number): WebGLRenderTarget;
|
|
203
|
+
/** Look up an FBO without creating one. */
|
|
204
|
+
get(entityId: EntityId): WebGLRenderTarget | null;
|
|
205
|
+
/**
|
|
206
|
+
* Refresh `lastUsedMs` without re-acquiring. The Compositor calls this
|
|
207
|
+
* for every widget it samples in the composition pass — without it,
|
|
208
|
+
* Warm widgets that never repaint would freeze their `lastUsedMs` at
|
|
209
|
+
* the time of their last paint, and eviction LRU would treat
|
|
210
|
+
* still-visible widgets as stale.
|
|
211
|
+
*/
|
|
212
|
+
touch(entityId: EntityId): void;
|
|
213
|
+
/**
|
|
214
|
+
* Release `entityId`'s FBO. Returns true if something was released.
|
|
215
|
+
* Safe to call after dispose — returns false rather than corrupting the
|
|
216
|
+
* byte counter or double-disposing the target.
|
|
217
|
+
*/
|
|
218
|
+
release(entityId: EntityId): boolean;
|
|
219
|
+
/** Total GPU bytes consumed by the pool. */
|
|
220
|
+
bytesUsed(): number;
|
|
221
|
+
/** Number of FBOs currently held. */
|
|
222
|
+
size(): number;
|
|
223
|
+
/** True after `dispose()` — callers should re-create the pool instead of using it. */
|
|
224
|
+
isDisposed(): boolean;
|
|
225
|
+
/** Iterate live entries. */
|
|
226
|
+
forEach(cb: (entityId: EntityId, rt: WebGLRenderTarget) => void): void;
|
|
227
|
+
/**
|
|
228
|
+
* Snapshot of every live entry's `bytes` + `lastUsedMs` — input for the
|
|
229
|
+
* eviction algorithm in {@link selectEvictions}.
|
|
230
|
+
*/
|
|
231
|
+
entryInfos(): PoolEntryInfo[];
|
|
232
|
+
/** Dispose every FBO. After this, acquire throws and release returns false. */
|
|
233
|
+
dispose(): void;
|
|
234
|
+
}
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region src/r3f/compositor/CompositorContext.d.ts
|
|
237
|
+
/**
|
|
238
|
+
* Per-widget registration entry the Compositor needs in order to paint
|
|
239
|
+
* the widget's scene into its FBO each frame.
|
|
240
|
+
*/
|
|
241
|
+
type CompositorWidgetEntry = {
|
|
242
|
+
scene: Scene;
|
|
243
|
+
camera: OrthographicCamera;
|
|
244
|
+
/**
|
|
245
|
+
* Bumped by the widget when its content has changed and needs a repaint.
|
|
246
|
+
* Compared against fboGeneration in R3FRenderState.
|
|
247
|
+
*/
|
|
248
|
+
requestRepaint: () => void;
|
|
249
|
+
};
|
|
250
|
+
type CompositorContextValue = {
|
|
251
|
+
pool: WidgetRenderTargetPool;
|
|
252
|
+
registry: ResourceRegistry;
|
|
253
|
+
register: (entityId: EntityId, entry: CompositorWidgetEntry) => () => void;
|
|
254
|
+
};
|
|
255
|
+
declare const CompositorContext: _$react.Context<CompositorContextValue | null>;
|
|
256
|
+
declare function useCompositor(): CompositorContextValue;
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/r3f/compositor/WidgetRegistry.d.ts
|
|
259
|
+
/**
|
|
260
|
+
* Stable per-canvas registry of R3F widget scenes + cameras (RFC-006).
|
|
261
|
+
*
|
|
262
|
+
* Created in `R3FManager` so it's reachable both by the `Compositor`
|
|
263
|
+
* (which adds/removes widgets as `VirtualWidget` mounts) and by the
|
|
264
|
+
* R3F event factory (which resolves the active widget by entityId
|
|
265
|
+
* returned from `engine.pickAt`, then looks up its scene + camera here).
|
|
266
|
+
*
|
|
267
|
+
* Plain Map under the hood — the wrapping class exists to give the
|
|
268
|
+
* registry a stable identity across React renders and to keep the read
|
|
269
|
+
* surface (`get`, `keys`, `all`) discoverable from both consumers.
|
|
270
|
+
*/
|
|
271
|
+
declare class WidgetRegistry {
|
|
272
|
+
private readonly entries;
|
|
273
|
+
register(entityId: EntityId, entry: CompositorWidgetEntry): () => void;
|
|
274
|
+
get(entityId: EntityId): CompositorWidgetEntry | undefined;
|
|
275
|
+
all(): IterableIterator<[EntityId, CompositorWidgetEntry]>;
|
|
276
|
+
keys(): IterableIterator<EntityId>;
|
|
277
|
+
values(): IterableIterator<CompositorWidgetEntry>;
|
|
278
|
+
clear(): void;
|
|
279
|
+
}
|
|
280
|
+
//#endregion
|
|
281
|
+
//#region src/r3f/compositor/Compositor.d.ts
|
|
282
|
+
/**
|
|
283
|
+
* Drives the per-widget paint + composition render loop (RFC-002 Phase 4).
|
|
284
|
+
*
|
|
285
|
+
* Lifecycle each invalidation:
|
|
286
|
+
* 1. For every registered widget whose phase is Hot or Waking (or whose
|
|
287
|
+
* paintGeneration > fboGeneration), bind its FBO and render its scene
|
|
288
|
+
* with its widget-local camera.
|
|
289
|
+
* 2. Update each widget's composition quad (position, scale, texture).
|
|
290
|
+
* 3. Render the composition scene to the canvas backbuffer with a
|
|
291
|
+
* world-space orthographic camera matching the engine camera.
|
|
292
|
+
*
|
|
293
|
+
* Owns the `WidgetRenderTargetPool`. Children mount `<VirtualWidget />`
|
|
294
|
+
* instances which register their scene+camera via context.
|
|
295
|
+
*
|
|
296
|
+
* Replaces the old `R3FWidgetSlot` + `CameraSync` pair.
|
|
297
|
+
*/
|
|
298
|
+
declare function Compositor({
|
|
299
|
+
engine,
|
|
300
|
+
widgetRegistry,
|
|
301
|
+
children
|
|
302
|
+
}: {
|
|
303
|
+
engine: LayoutEngine;
|
|
304
|
+
/**
|
|
305
|
+
* Stable per-canvas widget registry created in `R3FManager`. Shared
|
|
306
|
+
* with the R3F event factory so the EventRouter (RFC-006) can resolve
|
|
307
|
+
* which widget owns a pointer event without a separate registration
|
|
308
|
+
* path. The Compositor populates it on `register` / unregister; reads
|
|
309
|
+
* it back during the paint + composition loop.
|
|
310
|
+
*/
|
|
311
|
+
widgetRegistry: WidgetRegistry;
|
|
312
|
+
children: React.ReactNode;
|
|
313
|
+
}): _$react_jsx_runtime0.JSX.Element;
|
|
314
|
+
//#endregion
|
|
315
|
+
//#region src/r3f/compositor/state.d.ts
|
|
316
|
+
/**
|
|
317
|
+
* Compositor state-machine phase for an R3F widget (RFC-002).
|
|
318
|
+
*
|
|
319
|
+
* - `Hot` — Active + Visible + animating. Ticks + paints every invalidation.
|
|
320
|
+
* - `Warm` — Active + Visible + idle. Texture cached, no tick, no paint.
|
|
321
|
+
* - `Waking` — Active + Visible but no valid texture yet (just un-culled / un-dormant). One-shot paint then → `Warm`.
|
|
322
|
+
* - `Cold` — Active + Culled. Off-screen, texture eviction-eligible.
|
|
323
|
+
* - `Dormant` — Not Active. Eviction-protected so re-activation is instant.
|
|
324
|
+
*/
|
|
325
|
+
type R3FPhase = 'Hot' | 'Warm' | 'Cold' | 'Waking' | 'Dormant';
|
|
326
|
+
/** Pixel resolution + camera zoom at which a widget's texture was last painted. */
|
|
327
|
+
type R3FPaintedAt = {
|
|
328
|
+
width: number;
|
|
329
|
+
height: number;
|
|
330
|
+
dpr: number;
|
|
331
|
+
zoom: number;
|
|
332
|
+
};
|
|
333
|
+
/** Per-widget state tracked by the compositor. */
|
|
334
|
+
type R3FRenderStateData = {
|
|
335
|
+
phase: R3FPhase;
|
|
336
|
+
paintedAt: R3FPaintedAt; /** True while the widget has signalled an animation tick is in progress. */
|
|
337
|
+
animating: boolean; /** Bumped by widget state changes / animations that invalidate the texture. */
|
|
338
|
+
paintGeneration: number; /** Generation last successfully painted into the FBO. */
|
|
339
|
+
fboGeneration: number;
|
|
340
|
+
};
|
|
341
|
+
declare const R3FRenderState: _$_jamesyong42_reactive_ecs0.ComponentType<R3FRenderStateData>;
|
|
342
|
+
/**
|
|
343
|
+
* Opt-in tag — a widget that wants per-frame ticking sets this. The state
|
|
344
|
+
* machine treats `Visible + R3FAnimationSignal` as the trigger for `Hot`.
|
|
345
|
+
* Removing the tag transitions back to `Warm` when the widget settles.
|
|
346
|
+
*/
|
|
347
|
+
declare const R3FAnimationSignal: _$_jamesyong42_reactive_ecs0.TagType;
|
|
348
|
+
/** Global compositor memory + stagger budget. */
|
|
349
|
+
type R3FRenderBudgetData = {
|
|
350
|
+
/** Max bytes the widget render-target pool may consume. */maxBytes: number; /** Current pool consumption (written by the pool once it lands in Phase 4). */
|
|
351
|
+
currentBytes: number; /** Max widgets to repaint per composited frame. */
|
|
352
|
+
maxRepaintsPerFrame: number;
|
|
353
|
+
};
|
|
354
|
+
declare const R3FRenderBudget: _$_jamesyong42_reactive_ecs0.ResourceType<R3FRenderBudgetData>;
|
|
355
|
+
//#endregion
|
|
356
|
+
//#region src/r3f/compositor/hooks.d.ts
|
|
357
|
+
/**
|
|
358
|
+
* Marks the current R3F widget as actively animating. While `active` is true,
|
|
359
|
+
* the state machine places the widget in `Hot`; when false, it returns to
|
|
360
|
+
* `Warm` on the next frame.
|
|
361
|
+
*
|
|
362
|
+
* Widgets should call this whenever they want per-frame ticking (e.g. during
|
|
363
|
+
* a spring settle, hover lerp, or an external animation). Without this
|
|
364
|
+
* signal, `useFrame` bodies may still fire when the canvas re-renders for
|
|
365
|
+
* other reasons — check `useWidgetPhase() === 'Hot'` to early-exit work
|
|
366
|
+
* that's only meaningful during the animation.
|
|
367
|
+
*/
|
|
368
|
+
declare function useWidgetAnimation(entityId: EntityId, active: boolean): void;
|
|
369
|
+
/**
|
|
370
|
+
* Returns the current compositor phase for the widget. Re-renders when the
|
|
371
|
+
* phase changes.
|
|
372
|
+
*/
|
|
373
|
+
declare function useWidgetPhase(entityId: EntityId): R3FPhase | null;
|
|
374
|
+
/**
|
|
375
|
+
* Returns a function that schedules a one-shot repaint of the widget. Use
|
|
376
|
+
* when widget content changes outside of React's render cycle (e.g., a
|
|
377
|
+
* subscription to an external store, an imperative WebSocket message).
|
|
378
|
+
*
|
|
379
|
+
* Internally bumps `paintGeneration` so the compositor's dirty check picks
|
|
380
|
+
* the widget up on the next frame, and invalidates the canvas so that
|
|
381
|
+
* frame is actually scheduled.
|
|
382
|
+
*/
|
|
383
|
+
declare function useWidgetInvalidate(entityId: EntityId): () => void;
|
|
384
|
+
/**
|
|
385
|
+
* Acquires a shared geometry from the Compositor's `ResourceRegistry`,
|
|
386
|
+
* keyed by `cacheKey`. The factory runs only on first acquisition; later
|
|
387
|
+
* callers with the same key get the same instance. Released automatically
|
|
388
|
+
* on unmount; the registry disposes when the last holder releases.
|
|
389
|
+
*
|
|
390
|
+
* Use for geometries that are expensive to build and frequently identical
|
|
391
|
+
* across widget instances — e.g. preset card backs.
|
|
392
|
+
*/
|
|
393
|
+
declare function useSharedGeometry<T extends BufferGeometry>(cacheKey: string, factory: () => T): T;
|
|
394
|
+
/** Same contract as {@link useSharedGeometry}, for materials. */
|
|
395
|
+
declare function useSharedMaterial<T extends Material>(cacheKey: string, factory: () => T): T;
|
|
396
|
+
/** Same contract as {@link useSharedGeometry}, for textures. */
|
|
397
|
+
declare function useSharedTexture<T extends Texture>(cacheKey: string, factory: () => T): T;
|
|
398
|
+
//#endregion
|
|
399
|
+
//#region src/r3f/compositor/VirtualWidget.d.ts
|
|
400
|
+
/**
|
|
401
|
+
* Mounts one R3F widget into its own Three.js scene + ortho camera so it
|
|
402
|
+
* can be painted into a private `WebGLRenderTarget` instead of the main
|
|
403
|
+
* canvas backbuffer.
|
|
404
|
+
*
|
|
405
|
+
* The user component is rendered in widget-local space — origin at centre,
|
|
406
|
+
* X right, Y up, dimensions = (Transform2D.width, Transform2D.height) in
|
|
407
|
+
* frame-local world units.
|
|
408
|
+
* That matches the contract the previous `R3FWidgetSlot` exposed, so user
|
|
409
|
+
* widget code (e.g. `geometry-card`) needs no changes.
|
|
410
|
+
*
|
|
411
|
+
* VirtualWidget itself does not paint or composite — that's the
|
|
412
|
+
* Compositor's job. We just create the scene/camera and register them so
|
|
413
|
+
* the Compositor can iterate widgets in its render loop.
|
|
414
|
+
*/
|
|
415
|
+
declare function VirtualWidget({
|
|
416
|
+
entityId,
|
|
417
|
+
component: Component
|
|
418
|
+
}: {
|
|
419
|
+
entityId: EntityId;
|
|
420
|
+
component: React.ComponentType<R3FWidgetProps>;
|
|
421
|
+
}): _$react.JSX.Element | null;
|
|
422
|
+
//#endregion
|
|
423
|
+
//#region src/r3f/compositor/WidgetStateMachine.d.ts
|
|
424
|
+
/**
|
|
425
|
+
* Updates `R3FRenderState` phases for every R3F (`surface === 'webgl'`)
|
|
426
|
+
* widget after each engine tick.
|
|
427
|
+
*
|
|
428
|
+
* At this phase the state machine is bookkeeping only — it does not
|
|
429
|
+
* allocate or paint render targets (that arrives in Phase 4). Consumers
|
|
430
|
+
* such as widget `useFrame` callbacks read the phase to decide whether
|
|
431
|
+
* to do work this frame.
|
|
432
|
+
*
|
|
433
|
+
* Transition rules match RFC-002 § State machine:
|
|
434
|
+
*
|
|
435
|
+
* Active + Visible + R3FAnimationSignal → Hot
|
|
436
|
+
* Active + Visible (idle) → Warm (or Waking if texture invalid — irrelevant pre-Phase-4)
|
|
437
|
+
* Active + Culled → Cold
|
|
438
|
+
* !Active → Dormant
|
|
439
|
+
*/
|
|
440
|
+
declare function WidgetStateMachine({
|
|
441
|
+
engine
|
|
442
|
+
}: {
|
|
443
|
+
engine: LayoutEngine;
|
|
444
|
+
}): null;
|
|
445
|
+
//#endregion
|
|
446
|
+
//#region src/r3f/compositor/ZoomBands.d.ts
|
|
447
|
+
/**
|
|
448
|
+
* Hysteresis-banded zoom-resolution policy (RFC-002 § Zoom handling).
|
|
449
|
+
*
|
|
450
|
+
* A widget's FBO is allocated at `widget bounds × dpr × band(zoom)` pixels.
|
|
451
|
+
* As long as the camera zoom stays within `[band × 0.5, band × 2]` of the
|
|
452
|
+
* band the widget was painted at, no repaint is needed — the composition
|
|
453
|
+
* shader does a small up/down sample. Crossing that gap triggers a repaint
|
|
454
|
+
* at the new band, snapping back to a 1:1 (or near-1:1) sample ratio.
|
|
455
|
+
*
|
|
456
|
+
* Bands are powers of 2 so each band covers a 4× display range. With the
|
|
457
|
+
* default ladder (0.0625 ↔ 16) we span camera zooms 0.03125 ↔ 32 — covering
|
|
458
|
+
* essentially every realistic infinite-canvas zoom level.
|
|
459
|
+
*/
|
|
460
|
+
declare const ZOOM_BANDS: readonly [0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16];
|
|
461
|
+
/**
|
|
462
|
+
* Pick the band whose `[band × 0.5, band × 2]` range contains the current
|
|
463
|
+
* zoom. The smallest band ≥ zoom (after rounding to a band edge) is the
|
|
464
|
+
* canonical choice — keeps the texture resolution at or above what the
|
|
465
|
+
* display needs.
|
|
466
|
+
*/
|
|
467
|
+
declare function selectBand(zoom: number): number;
|
|
468
|
+
/**
|
|
469
|
+
* Returns true if the widget needs to be repainted because the camera
|
|
470
|
+
* zoom has wandered outside the tolerance window of the band it was
|
|
471
|
+
* painted at.
|
|
472
|
+
*
|
|
473
|
+
* `paintedBand` of 0 (or negative) means the widget has never been
|
|
474
|
+
* painted yet — caller should treat that as "needs paint" through other
|
|
475
|
+
* channels (Waking phase / paintGeneration > fboGeneration).
|
|
476
|
+
*/
|
|
477
|
+
declare function isOutOfBand(currentZoom: number, paintedBand: number): boolean;
|
|
478
|
+
//#endregion
|
|
479
|
+
export { SelectionConfig as A, ContainerRefProvider as B, useCompositor as C, SnapGuideConfig as D, DEFAULT_SNAP_GUIDE_CONFIG as E, ResolvedWidget as F, WidgetResolverProvider as I, useWidgetResolver as L, DEFAULT_GRID_CONFIG as M, GridConfig as N, DEFAULT_SELECTION_CONFIG as O, GridRenderer as P, EngineProvider as R, CompositorWidgetEntry as S, ResourceRegistry as T, useContainerRef as V, R3FRenderState as _, VirtualWidget as a, CompositorContext as b, useSharedTexture as c, useWidgetPhase as d, R3FAnimationSignal as f, R3FRenderBudgetData as g, R3FRenderBudget as h, WidgetStateMachine as i, SelectionRenderer as j, SelectionBounds as k, useWidgetAnimation as l, R3FPhase as m, isOutOfBand as n, useSharedGeometry as o, R3FPaintedAt as p, selectBand as r, useSharedMaterial as s, ZOOM_BANDS as t, useWidgetInvalidate as u, R3FRenderStateData as v, WidgetRenderTargetPool as w, CompositorContextValue as x, Compositor as y, useLayoutEngine as z };
|
|
480
|
+
//# sourceMappingURL=index-3GY7T8JM.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-3GY7T8JM.d.mts","names":[],"sources":["../src/react/context/container-ref-context.ts","../src/react/context/engine-context.ts","../src/react/context/widget-resolver-context.ts","../src/webgl/renderers/GridRenderer.ts","../src/webgl/renderers/SelectionRenderer.ts","../src/webgl/renderers/SnapGuideRenderer.ts","../src/r3f/compositor/ResourceRegistry.ts","../src/r3f/compositor/WidgetRenderTargetPool.ts","../src/r3f/compositor/CompositorContext.tsx","../src/r3f/compositor/WidgetRegistry.ts","../src/r3f/compositor/Compositor.tsx","../src/r3f/compositor/state.ts","../src/r3f/compositor/hooks.ts","../src/r3f/compositor/VirtualWidget.tsx","../src/r3f/compositor/WidgetStateMachine.tsx","../src/r3f/compositor/ZoomBands.ts"],"mappings":"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"}
|