A React-based scene editor interface for Decentraland, providing a modular architecture for scene editing and manipulation.
- Entity Hierarchy: Tree-based scene management with component operations
- Component Inspector: Specialized editors for all component types
- Level Editor: 3D scene visualization with Babylon.js
- Asset Management: Local assets, custom items, and asset packs support
npm install @dcl/inspector
- Start the CLI server:
npx @dcl/sdk-commands start --data-layer --port 8001
- Serve the inspector (choose one method):
# Method 1: Development server
git clone https://github.com/decentraland/js-sdk-toolchain.git
cd packages/@dcl/inspector
npm start
# Method 2: From node_modules
npm install @dcl/inspector
npx http-server node_modules/@dcl/inspector/public
- Access the Inspector:
http://localhost:3000/?dataLayerRpcWsUrl=ws://127.0.0.1:8001/data-layer
Where http://localhost:3000
is the URL of the Inspector and ws://127.0.0.1:8001/data-layer
is the WebSocket URL of the CLI server.
The Inspector supports two integration approaches:
For development environments using the CLI:
// Connect to CLI's WebSocket server
const inspectorUrl = `http://localhost:3000/?dataLayerRpcWsUrl=ws://127.0.0.1:8001/data-layer`
For web applications embedding the Inspector:
function initRpc(iframe: HTMLIFrameElement) {
const transport = new MessageTransport(window, iframe.contentWindow!)
const storage = new StorageRPC(transport)
// Handle file operations
storage.handle('read_file', async ({ path }) => {
return fs.readFile(path)
})
storage.handle('write_file', async ({ path, content }) => {
await fs.writeFile(path, content)
})
// ... other handlers
return {
storage,
dispose: () => storage.dispose()
}
}
function InspectorComponent() {
const iframeRef = useRef()
const handleIframeRef = useCallback((iframe) => {
if (iframe) {
iframeRef.current = initRpc(iframe)
}
}, [])
useEffect(() => {
return () => iframeRef.current?.dispose()
}, [])
const params = new URLSearchParams({
dataLayerRpcParentUrl: window.location.origin
})
const inspectorUrl = `http://localhost:3000/`
const url = `${inspectorUrl}?${params}`
return <iframe onLoad={handleIframeRef} src={url} />
}
Configure the Inspector through URL parameters or a global object. All configuration options can be set using either method:
type InspectorConfig = {
// Data Layer Configuration
dataLayerRpcWsUrl: string | null // ?dataLayerRpcWsUrl=ws://...
dataLayerRpcParentUrl: string | null // ?dataLayerRpcParentUrl=https://...
// Smart Items Configuration
binIndexJsUrl: string | null // ?binIndexJsUrl=https://...
disableSmartItems: boolean // ?disableSmartItems=true
// Content Configuration
contentUrl: string // ?contentUrl=https://...
// Analytics Configuration
segmentKey: string | null // ?segmentKey=...
segmentAppId: string | null // ?segmentAppId=...
segmentUserId: string | null // ?segmentUserId=...
projectId: string | null // ?projectId=...
}
// Method 1: Global configuration
globalThis.InspectorConfig = {
dataLayerRpcWsUrl: 'ws://127.0.0.1:8001/data-layer',
contentUrl: 'https://builder-items.decentraland.org'
}
// Method 2: URL parameters
// http://localhost:3000/?dataLayerRpcWsUrl=ws://127.0.0.1:8001/data-layer&contentUrl=https://builder-items.decentraland.org&disableSmartItems=true
Configuration options are resolved in the following order:
- URL parameters (highest priority)
- Global object
- Default values (lowest priority)
Run all inspector tests:
make test-inspector
Run specific test files in watch mode:
make test-inspector FILES="--watch packages/@dcl/inspector/src/path/to/some-test.spec.ts"
-
WebSocket Connection
- Verify CLI server is running with
--data-layer
flag - Check WebSocket URL matches CLI server port
- Ensure no firewall blocking connection
- Verify CLI server is running with
-
File System Access
- Check file permissions
- Verify CLI has necessary access rights
- Ensure paths are correctly formatted
-
Asset Loading
- Verify
contentUrl
is correctly configured - Check network access to content server
- Ensure asset paths are valid
- Verify
-
Debugging
- Use Chrome DevTools for WebSocket inspection
- Enable React DevTools
- Monitor browser console for RPC messages
-
Testing
- Use in-memory implementation for unit tests
- Mock RPC calls for integration testing
- Test both WebSocket and IFrame transport
For a deeper understanding of the architecture and design decisions:
- ADR-281: Items in Decentraland tooling - Explains the Items abstraction and how it's used in the Inspector
- ADR-282: Decentraland Inspector - Details the Inspector's architecture, integration approaches, and technical decisions
Apache 2.0