DevtoolProbe Class
The DevtoolProbe class is the central API for 3Lens. It manages renderer observation, scene tracking, object selection, performance monitoring, and communication with the overlay/extension.
Import
import { DevtoolProbe, createProbe } from '@3lens/core';Recommended
Use createProbe() to create instances instead of new DevtoolProbe() directly. The factory handles auto-connection to the browser extension.
Class Overview
class DevtoolProbe {
// Configuration
readonly config: ProbeConfig;
// Properties
get threeVersion(): string | null;
get entityCount(): number;
get moduleCount(): number;
get pluginCount(): number;
get activePluginCount(): number;
// Renderer Management
observeRenderer(renderer: THREE.WebGLRenderer | THREE.Renderer): void;
isWebGL(): boolean;
isWebGPU(): boolean;
getRendererKind(): 'webgl' | 'webgpu' | null;
getRendererAdapter(): RendererAdapter | null;
// Scene Management
observeScene(scene: THREE.Scene): void;
unobserveScene(scene: THREE.Scene): void;
getObservedScenes(): THREE.Scene[];
// Selection
selectObject(obj: THREE.Object3D | null): void;
selectByDebugId(debugId: string | null): boolean;
getSelectedObject(): THREE.Object3D | null;
onSelectionChanged(callback): Unsubscribe;
// Inspect Mode
initializeInspectMode(canvas, camera, three): void;
setInspectModeEnabled(enabled: boolean): void;
isInspectModeEnabled(): boolean;
// Frame Stats
getLatestFrameStats(): FrameStats | null;
getFrameStatsHistory(count?: number): FrameStats[];
onFrameStats(callback): Unsubscribe;
// Snapshots
takeSnapshot(): SceneSnapshot;
onSnapshot(callback): Unsubscribe;
// Lifecycle
connect(transport: Transport): void;
disconnect(): void;
isConnected(): boolean;
dispose(): void;
// ...and many more methods
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Constructor
constructor(config: ProbeConfig)Creates a new probe instance. Prefer using createProbe() instead.
| Parameter | Type | Description |
|---|---|---|
config | ProbeConfig | Probe configuration |
Properties
config
readonly config: ProbeConfigThe probe's configuration object (read-only after construction).
threeVersion
get threeVersion(): string | nullThe detected three.js version from the observed renderer. Returns null if no renderer is observed.
const probe = createProbe({ appName: 'My App' });
probe.observeRenderer(renderer);
console.log(probe.threeVersion); // "0.160.0"2
3
entityCount
get entityCount(): numberThe number of registered logical entities.
moduleCount
get moduleCount(): numberThe number of registered modules.
pluginCount
get pluginCount(): numberThe number of registered plugins.
activePluginCount
get activePluginCount(): numberThe number of currently active plugins.
Renderer Management
observeRenderer()
observeRenderer(renderer: THREE.WebGLRenderer | THREE.Renderer): voidStart observing a three.js renderer. Auto-detects WebGL vs WebGPU.
// WebGL Renderer
const renderer = new THREE.WebGLRenderer();
probe.observeRenderer(renderer);
// WebGPU Renderer
const gpuRenderer = new THREE.WebGPURenderer();
probe.observeRenderer(gpuRenderer);2
3
4
5
6
7
WebGPU Detection
The probe detects WebGPU renderers via the isWebGPURenderer property on the renderer object.
isWebGL()
isWebGL(): booleanReturns true if the current renderer is WebGL.
isWebGPU()
isWebGPU(): booleanReturns true if the current renderer is WebGPU.
getRendererKind()
getRendererKind(): 'webgl' | 'webgpu' | nullReturns the renderer backend type, or null if no renderer is observed.
getRendererAdapter()
getRendererAdapter(): RendererAdapter | nullReturns the internal renderer adapter for advanced use cases.
attachRendererAdapter()
attachRendererAdapter(adapter: RendererAdapter): voidAttach a custom renderer adapter. For advanced use when auto-detection isn't suitable.
Resource Queries
getTextures()
getTextures(): TextureInfo[]Get all textures tracked by the renderer.
getGeometries()
getGeometries(): GeometryInfo[]Get all geometries tracked by the renderer.
getMaterials()
getMaterials(): MaterialInfo[]Get all materials tracked by the renderer.
getGpuTimings()
async getGpuTimings(): Promise<GpuTimingInfo | null>Get GPU timing information (if available).
Scene Management
observeScene()
observeScene(scene: THREE.Scene): voidStart observing a scene for changes. Multiple scenes can be observed simultaneously.
const mainScene = new THREE.Scene();
const uiScene = new THREE.Scene();
probe.observeScene(mainScene);
probe.observeScene(uiScene);2
3
4
5
unobserveScene()
unobserveScene(scene: THREE.Scene): voidStop observing a scene.
getObservedScenes()
getObservedScenes(): THREE.Scene[]Get all currently observed scenes.
Render Target Management
observeRenderTarget()
observeRenderTarget(
renderTarget: THREE.WebGLRenderTarget,
usage?: RenderTargetUsage
): void2
3
4
Register a render target for observation.
| Parameter | Type | Default | Description |
|---|---|---|---|
renderTarget | WebGLRenderTarget | - | The render target to observe |
usage | RenderTargetUsage | 'custom' | Usage hint for categorization |
RenderTargetUsage values:
'shadow-map'- Shadow mapping'post-process'- Post-processing effects'reflection'- Environment reflections'refraction'- Refraction effects'custom'- Other uses
const depthTarget = new THREE.WebGLRenderTarget(1024, 1024);
probe.observeRenderTarget(depthTarget, 'post-process');2
unobserveRenderTarget()
unobserveRenderTarget(renderTarget: THREE.WebGLRenderTarget): voidStop observing a render target.
getRegisteredRenderTargets()
getRegisteredRenderTargets(): Map<string, {
rt: THREE.WebGLRenderTarget;
usage: RenderTargetUsage
}>2
3
4
Get all registered render targets.
THREE.js Reference
setThreeReference()
setThreeReference(three: typeof import('three')): voidProvide a reference to the THREE.js library. Required for:
- Selection highlighting (bounding boxes)
- Visualization helpers (wireframe, normals)
- Transform gizmos
import * as THREE from 'three';
const probe = createProbe({ appName: 'My App' });
probe.setThreeReference(THREE);2
3
4
updateSelectionHighlight()
updateSelectionHighlight(): voidManually update selection highlight. Call this in your animation loop if selected objects move.
Object Selection
See Selection API for detailed documentation.
selectObject()
selectObject(obj: THREE.Object3D | null): voidSelect an object or clear selection (pass null).
selectByDebugId()
selectByDebugId(debugId: string | null): booleanSelect an object by its debug ID. Returns true if found.
getSelectedObject()
getSelectedObject(): THREE.Object3D | nullGet the currently selected object.
onSelectionChanged()
onSelectionChanged(
callback: (obj: THREE.Object3D | null, meta?: ObjectMeta) => void
): Unsubscribe2
3
Subscribe to selection changes.
const unsubscribe = probe.onSelectionChanged((obj, meta) => {
if (obj) {
console.log('Selected:', meta?.name, obj.type);
} else {
console.log('Selection cleared');
}
});
// Later: unsubscribe()2
3
4
5
6
7
8
9
Inspect Mode
See Inspect Mode API for detailed documentation.
initializeInspectMode()
initializeInspectMode(
canvas: HTMLCanvasElement,
camera: THREE.Camera,
three: typeof import('three')
): void2
3
4
5
Initialize inspect mode for interactive object picking.
setInspectModeEnabled()
setInspectModeEnabled(enabled: boolean): voidEnable or disable inspect mode.
isInspectModeEnabled()
isInspectModeEnabled(): booleanCheck if inspect mode is currently enabled.
setInspectModeCamera()
setInspectModeCamera(camera: THREE.Camera): voidUpdate the camera used for raycasting.
setInspectModePickableObjects()
setInspectModePickableObjects(objects: THREE.Object3D[]): voidLimit which objects can be picked.
Visual Overlays
toggleWireframe()
toggleWireframe(obj: THREE.Object3D, enabled: boolean): voidToggle wireframe visualization for an object.
toggleBoundingBox()
toggleBoundingBox(obj: THREE.Object3D, enabled: boolean): voidToggle bounding box visualization for an object.
toggleGlobalWireframe()
toggleGlobalWireframe(enabled: boolean): voidToggle wireframe mode for all meshes in all scenes.
isWireframeEnabled()
isWireframeEnabled(obj: THREE.Object3D): booleanCheck if wireframe is enabled for an object.
isBoundingBoxEnabled()
isBoundingBoxEnabled(obj: THREE.Object3D): booleanCheck if bounding box is enabled for an object.
Frame Stats
getLatestFrameStats()
getLatestFrameStats(): FrameStats | nullGet the most recent frame statistics.
const stats = probe.getLatestFrameStats();
if (stats) {
console.log(`FPS: ${stats.performance?.fps}`);
console.log(`Draw calls: ${stats.drawCalls}`);
console.log(`Triangles: ${stats.triangles}`);
}2
3
4
5
6
getFrameStatsHistory()
getFrameStatsHistory(count?: number): FrameStats[]Get historical frame stats. Defaults to all history (up to 300 frames).
// Get last 60 frames
const history = probe.getFrameStatsHistory(60);
const avgFps = history.reduce((sum, s) => sum + (s.performance?.fps ?? 0), 0) / history.length;2
3
onFrameStats()
onFrameStats(callback: (stats: FrameStats) => void): UnsubscribeSubscribe to frame stats updates.
const unsubscribe = probe.onFrameStats((stats) => {
updateDebugDisplay(stats);
});2
3
Snapshots
takeSnapshot()
takeSnapshot(): SceneSnapshotManually capture a snapshot of all observed scenes.
onSnapshot()
onSnapshot(callback: (snapshot: SceneSnapshot) => void): UnsubscribeSubscribe to snapshot events.
Custom Metrics
metric()
metric(name: string, value: number, tags?: Record<string, string>): voidRecord a custom metric value.
probe.metric('enemy-count', enemies.length, { level: 'boss' });
probe.metric('particle-count', particleSystem.count);2
event()
event(name: string, data?: Record<string, unknown>): voidRecord a custom event.
probe.event('level-complete', { level: 5, time: 120, score: 15000 });Material Live Editing
updateMaterialProperty()
updateMaterialProperty(
materialUuid: string,
property: string,
value: unknown
): void2
3
4
5
Update a material property by UUID. Used for live editing from the overlay.
// Change material color
probe.updateMaterialProperty(material.uuid, 'color', 0xff0000);
// Change roughness
probe.updateMaterialProperty(material.uuid, 'roughness', 0.5);2
3
4
5
Transport & Connection
connect()
connect(transport: Transport): voidConnect to a transport for communication with devtools.
disconnect()
disconnect(): voidDisconnect from the current transport.
isConnected()
isConnected(): booleanCheck if connected to a devtool UI.
onCommand()
onCommand(handler: (command: DebugMessage) => void): UnsubscribeHandle commands from the devtool UI.
Lifecycle
See Probe Lifecycle for detailed documentation.
dispose()
dispose(): voidClean up all resources. Always call this when done.
// React cleanup
useEffect(() => {
const probe = createProbe({ appName: 'My App' });
return () => probe.dispose();
}, []);2
3
4
5
Additional Systems
The DevtoolProbe also provides access to:
- Transform Gizmo - 3D manipulation controls
- Camera Controller - Focus, fly-to animations
- Logical Entities - Component ↔ Object mapping
- Plugin System - Extensibility
- Configuration - Rule checking
See their respective documentation pages for details.
Type Definitions
FrameStats
interface FrameStats {
timestamp: number;
frameNumber: number;
drawCalls: number;
triangles: number;
points: number;
lines: number;
geometryCount: number;
textureCount: number;
programCount: number;
memory?: MemoryStats;
performance?: PerformanceMetrics;
violations?: RuleViolation[];
}2
3
4
5
6
7
8
9
10
11
12
13
14
ObjectMeta
interface ObjectMeta {
debugId: string;
uuid: string;
name: string;
type: string;
visible: boolean;
path: string;
}2
3
4
5
6
7
8
Unsubscribe
type Unsubscribe = () => void;Related
- createProbe() - Factory function
- Probe Lifecycle - init, dispose, connect
- Selection API - Object selection details
- Inspect Mode API - Interactive picking
- FrameStats Reference - Stats structure