Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ragaeeb/dyelight/llms.txt

Use this file to discover all available pages before exploring further.

DyeLight includes a built-in telemetry system that helps diagnose synchronization issues between the textarea and React state. This is especially useful for hard-to-reproduce bugs.

Enabling debug mode

Add the debug prop to enable telemetry collection:
import { useRef, useState } from 'react';
import { DyeLight, type DyeLightRef } from 'dyelight';

function DebugExample() {
    const [text, setText] = useState('');
    const dyeLightRef = useRef<DyeLightRef>(null);

    const handleExportDebug = async () => {
        const report = dyeLightRef.current?.exportForAI();
        
        if (report) {
            await navigator.clipboard.writeText(report);
            alert('Debug report copied!');
        }
    };

    return (
        <div>
            <DyeLight
                ref={dyeLightRef}
                value={text}
                onChange={setText}
                debug={true}
                rows={10}
            />
            
            <button onClick={handleExportDebug}>
                Export debug report
            </button>
        </div>
    );
}
Debug mode has minimal performance impact but should generally be disabled in production unless troubleshooting specific issues.

Using the exportForAI() method

The exportForAI() ref method generates a comprehensive JSON report that can be analyzed by AI models:
const dyeLightRef = useRef<DyeLightRef>(null);

// Export debug data when issues occur
const report = dyeLightRef.current?.exportForAI();
When you experience sync issues:
  1. Enable debug mode - Add debug={true} to your DyeLight component
  2. Reproduce the issue - Use the component normally until the bug occurs
  3. Export the report - Call ref.current?.exportForAI() to get a JSON report
  4. Get AI diagnosis:
    • Go to claude.ai or chat.openai.com
    • Paste the exported JSON
    • Ask: “Please analyze this DyeLight debug report and identify the issue”
  5. Get instant diagnosis - The AI will identify the root cause and suggest fixes

What’s included in debug reports

The telemetry system captures comprehensive diagnostic data:

Event timeline

Every interaction is recorded with millisecond precision:
  • onChange events from user typing/pasting
  • Auto-resize operations
  • Scroll synchronization
  • Style synchronization between textarea and overlay

State snapshots

At each event, the system captures:
  • DOM value vs React state value
  • Textarea and overlay geometry (width, height, scroll position)
  • Selection range (cursor position)
  • Layout deltas between textarea and overlay

Automatic issue detection

The system pre-identifies common problems:
State mismatches - When DOM value differs from React state (critical issue)
  • Rapid successive events - Events firing less than 2ms apart indicate race conditions
  • Excessive resize operations - More resizes than value changes suggests infinite ResizeObserver loop
  • Large paste operations - Pastes >100 characters that may trigger sync issues
  • Layout thrashing - High frequency of sync operations

Timing information

Each event includes:
  • Absolute timestamp (ISO format)
  • Time since last event (milliseconds)
  • Event category (user, state, sync, system)

Browser metadata

The report includes environmental context:
  • User agent string
  • Platform information
  • Component version
  • Total event count and timespan

Telemetry system architecture

The telemetry system is implemented in src/telemetry.ts and uses several optimization strategies:

Value deduplication

Large text values (>1000 characters) are stored once in a valueRegistry and referenced as <REF:value_N>. This prevents the JSON from becoming huge when users paste large blocks of text.
{
  "stateSnapshot": {
    "textareaValue": "<REF:value_0>",
    "reactValue": "<REF:value_0>"
  }
}
// Look up actual value in:
"valueRegistry": {
  "<REF:value_0>": "...actual 40KB text here..."
}
When analyzing reports, always check the valueRegistry when you see <REF:value_N> references.

Event categorization

Events are categorized for easier analysis:
  • user: Direct user interactions (typing, pasting, selection changes)
  • state: Programmatic state changes (setValue, etc.)
  • sync: Layout synchronization operations (syncStyles, syncScroll)
  • system: Periodic snapshots and background tasks

Memory management

The telemetry system maintains a circular buffer of events:
<DyeLight
    debug={true}
    debugMaxEvents={1000}  // Max events to retain (default: 1000)
    value={text}
    onChange={setText}
/>
When the buffer is full, oldest events are discarded to prevent memory bloat.

Debug mode options

PropTypeDefaultDescription
debugbooleanfalseEnable telemetry collection
debugMaxEventsnumber1000Maximum events to retain in memory

Common issue patterns

The AI analysis looks for these patterns:

State desynchronization

{
  "stateSnapshot": {
    "valuesMatch": false,
    "textareaValue": "<REF:value_0>",
    "reactValue": "<REF:value_1>"
  }
}
Indicates DOM and React state are out of sync. Often caused by:
  • Multiple onChange handlers bound to the textarea
  • Direct DOM manipulation from external code
  • Race conditions during paste operations

Race conditions

Events firing less than 2ms apart:
{
  "timeSinceLastEvent": 1.2,
  "anomalies": ["Rapid event: 1.2ms since last event"]
}
Suggests:
  • Double-bound event listeners
  • Need for debouncing in user code

Infinite resize loop

More resize events than value changes indicates a ResizeObserver feedback loop:
{
  "summary": {
    "suspiciousPatterns": [
      "Excessive resize operations (450 resizes vs 23 value changes)"
    ]
  }
}

Build docs developers (and LLMs) love