npm package: @not-true/devtools
Description: Remote debugging and development tools client library for React Native applications
Author: Remote DevTools Platform
Latest version: 2.1.4

# @not-true/devtools

Remote debugging and development tools client library for React Native applications.

## Features

- 🔧 **Real-time Console Logging** - Automatically capture and stream console output
- 🎮 **Remote REPL** - Execute JavaScript commands remotely on your device
- 📱 **Screenshot Capture** - Take screenshots of your app remotely
- 🔄 **State Synchronization** - Monitor Redux, Context, and AsyncStorage state
- ⚙️ **Remote Configuration** - Update feature flags and config dynamically
- 🔌 **Automatic Reconnection** - Robust connection handling with queue management
- 📊 **Device Information** - Collect and display device/app metadata
- 🚀 **TypeScript Support** - Fully typed for better developer experience

## Installation

```bash
npm install @not-true/devtools
# or
yarn add @not-true/devtools
```

### Dependencies

The package includes socket.io-client 2.5.0 which is optimized for React Native compatibility:

```bash
npm install @not-true/devtools
# socket.io-client 2.5.0 is included as a dependency
```

## Quick Start

### Basic Setup

```typescript
import RemoteDevTools from '@not-true/devtools';

const devTools = new RemoteDevTools({
  serverUrl: 'http://your-devtools-server:3000',
  name: 'My React Native App',
  version: '1.0.0',
}, {
  onConnect: () => console.log('Connected to DevTools'),
  onDisconnect: () => console.log('Disconnected from DevTools'),
});

// Connect to the server
await devTools.connect();
```

### With React Hooks

```typescript
import React, { useEffect } from 'react';
import { useRemoteDevTools, useReduxSync } from '@not-true/devtools';
import { store } from './store'; // Your Redux store

function App() {
  const { devTools, isConnected, connect, connectionStatus } = useRemoteDevTools({
    serverUrl: 'http://localhost:3000',
    name: 'My App',
    version: '1.0.0',
  }, {
    onConnect: () => console.log('DevTools connected!'),
    onRemoteConfig: (config) => {
      // Handle remote configuration updates
      console.log('Received config:', config);
    },
  });

  // Automatically sync Redux state
  useReduxSync(devTools, store);

  useEffect(() => {
    connect();
  }, [connect]);

  return (
    <div>
      <p>DevTools Status: {connectionStatus}</p>
      {/* Your app content */}
    </div>
  );
}
```

## Configuration

### RemoteDevToolsConfig

```typescript
interface RemoteDevToolsConfig {
  serverUrl: string;                    // Required: WebSocket server URL
  name: string;                        // Required: Client display name
  version: string;                     // Required: Application version
  
  // Optional settings
  maxQueueSize?: number;               // Default: 1000
  maxReconnectAttempts?: number;       // Default: 5
  reconnectDelay?: number;             // Default: 1000ms

  // Feature toggles
  enableConsoleLogging?: boolean;      // Default: true
  enableStateSync?: boolean;           // Default: true
  enableScreenshots?: boolean;         // Default: true
  enableREPL?: boolean;               // Default: true
  enableRemoteConfig?: boolean;        // Default: true

  // Screenshot settings
  screenshotQuality?: number;          // 0-1, default: 0.8
  screenshotFormat?: 'png' | 'jpg';   // Default: 'png'

  // State sync settings
  stateUpdateThrottle?: number;        // ms, default: 500

  // Custom info
  deviceInfo?: object;
  clientInfo?: object;
}
```

## Usage Examples

### Manual Logging

```typescript
// These will be automatically captured if enableConsoleLogging is true
console.log('Hello from device!');
console.warn('Warning message');
console.error('Error occurred');

// Or send logs manually
devTools.log('info', 'Custom log message', { data: 'example' });
```

### State Synchronization

```typescript
// Redux state sync (automatic with useReduxSync hook)
import { StateUtils } from '@not-true/devtools';

const stateUpdate = StateUtils.createReduxStateUpdate(store.getState());
devTools.updateState(stateUpdate);

// Custom state sync
const customState = StateUtils.createCustomStateUpdate({
  userPreferences: { theme: 'dark', language: 'en' },
  featureFlags: { newUI: true }
}, 'app-state');
devTools.updateState(customState);

// AsyncStorage sync
const asyncStorageUpdate = StateUtils.createAsyncStorageUpdate('userToken', 'abc123');
devTools.updateState(asyncStorageUpdate);
```

### Screenshot Capture

The client library requires you to implement your own screenshot capture (e.g., using `react-native-view-shot` or similar):

```typescript
import { ScreenshotUtils } from '@not-true/devtools';
// You need to install and import your screenshot library
// import { captureScreen } from 'react-native-view-shot';

// Handle remote screenshot requests
const devTools = new RemoteDevTools(config, {
  onScreenshotRequest: async (options) => {
    // Implement your own screenshot capture
    const uri = await captureScreen({
      format: options.format || 'png',
      quality: options.quality || 0.8,
      result: 'data-uri' // or 'base64'
    });

    // Convert to base64 if needed
    const base64 = ScreenshotUtils.dataURIToBase64(uri);
    
    // Create screenshot data with metadata
    return ScreenshotUtils.createScreenshotWithMetadata(base64, {
      width: 375, // actual screen width
      height: 812, // actual screen height
      format: options.format || 'png'
    });
  }
});

// Send screenshot manually
const sendScreenshot = async () => {
  try {
    const uri = await captureScreen({ format: 'png', quality: 0.8 });
    const base64 = ScreenshotUtils.dataURIToBase64(uri);
    const screenshot = ScreenshotUtils.createScreenshotWithMetadata(base64, {
      width: 375,
      height: 812,
      format: 'png'
    });
    devTools.sendScreenshot(screenshot);
  } catch (error) {
    console.error('Screenshot failed:', error);
  }
};
```

### REPL Command Handling

```typescript
const devTools = new RemoteDevTools(config, {
  onREPLCommand: async (command) => {
    // Handle remote JavaScript execution
    try {
      // Safely evaluate the command
      if (command.command === 'getAppVersion()') {
        return '1.0.0';
      }
      
      if (command.command === 'getCurrentUser()') {
        return { id: 1, name: 'John Doe' };
      }
      
      // For security, limit what can be executed
      throw new Error('Command not allowed');
    } catch (error) {
      throw error;
    }
  }
});
```

### Remote Configuration

```typescript
const devTools = new RemoteDevTools(config, {
  onRemoteConfig: (config) => {
    // Apply configuration changes
    if (config.config.enableDarkMode) {
      // Enable dark mode
    }
    
    if (config.config.apiEndpoint) {
      // Update API endpoint
    }
    
    // Update feature flags
    updateFeatureFlags(config.config.featureFlags || {});
  }
});
```

### Context State Sync

```typescript
import React, { useContext } from 'react';
import { useContextSync } from '@not-true/devtools';

const ThemeContext = React.createContext({ theme: 'light' });

function MyComponent({ devTools }) {
  const themeValue = useContext(ThemeContext);
  
  // Automatically sync context value
  useContextSync(devTools, themeValue, 'ThemeContext');
  
  return <div>Component content</div>;
}
```

## Advanced Usage

### Custom Queue Management

```typescript
import { QueueManager } from '@not-true/devtools';

const customQueue = new QueueManager(500); // Custom size limit

// Manually manage queue
customQueue.enqueue({
  type: 'log',
  data: { level: 'info', message: 'Custom message' },
  timestamp: Date.now()
});

// Get queue stats
const stats = customQueue.getStats();
console.log(`Queue size: ${stats.size}/${stats.maxSize}`);
```

### Device Information

```typescript
import { DeviceInfoUtils } from '@not-true/devtools';

const deviceInfo = DeviceInfoUtils.getDeviceInfo();
console.log('Platform:', deviceInfo.platform);
console.log('OS Version:', deviceInfo.osVersion);
console.log('Screen Size:', deviceInfo.screenSize);

const memoryInfo = DeviceInfoUtils.getMemoryInfo();
const networkInfo = DeviceInfoUtils.getNetworkInfo();
```

### Error Handling

```typescript
const devTools = new RemoteDevTools(config, {
  onError: (error) => {
    console.error('DevTools error:', error);
    // Handle or report error
  },
  onReconnectError: (error) => {
    console.error('Failed to reconnect:', error);
    // Show user notification or fallback
  }
});
```

## API Reference

### RemoteDevTools Class

#### Methods

- `connect()`: Promise<void> - Connect to the server
- `disconnect()`: void - Disconnect from the server
- `log(level, ...args)`: void - Send log entry
- `updateState(stateUpdate)`: void - Send state update
- `sendScreenshot(data)`: void - Send screenshot data
- `sendREPLResult(result)`: void - Send REPL execution result
- `isConnectedToServer()`: boolean - Check connection status
- `getConfig()`: RemoteDevToolsConfig - Get current configuration
- `updateConfig(config)`: void - Update configuration
- `destroy()`: void - Cleanup and disconnect

### React Hooks

- `useRemoteDevTools(config, handlers)` - Main hook for RemoteDevTools integration
- `useReduxSync(devTools, store, throttleMs?)` - Automatic Redux state synchronization
- `useREPLHandler(devTools, evaluator?)` - REPL command handling
- `useScreenshotHandler(devTools, capturer?)` - Screenshot request handling
- `useContextSync(devTools, contextValue, name, throttleMs?)` - React Context synchronization

### Utility Classes

- `DeviceInfoUtils` - Device and platform information
- `QueueManager` - Message queue management
- `ScreenshotUtils` - Screenshot capture utilities
- `StateUtils` - State management helpers

## Development Server

This client library works with the Remote DevTools Platform server. To set up the server:

```bash
# Clone the server repository
git clone https://github.com/your-org/remote-devtools-platform
cd remote-devtools-platform

# Install dependencies
npm install

# Start development server
npm run dev

# Or start production server
npm run build && npm start
```

The dashboard will be available at `http://localhost:3000`.

## Security Considerations

- **REPL Execution**: The remote REPL feature allows arbitrary code execution. Only use in development environments.
- **Network Security**: Use HTTPS/WSS in production environments.
- **Data Sanitization**: State data is automatically sanitized to prevent large payloads and circular references.
- **Access Control**: Implement proper authentication/authorization in your server setup.

## Platform Support

- ✅ React Native (iOS/Android)
- ✅ Expo (managed/bare workflow)
- ⚠️ Web (limited screenshot support)
- ❌ React Native Windows/macOS (not tested)

## Troubleshooting

### Connection Issues

```typescript
// Check if server is accessible
const devTools = new RemoteDevTools(config, {
  onConnect: () => console.log('✅ Connected'),
  onDisconnect: () => console.log('❌ Disconnected'),
  onReconnect: (attempt) => console.log(`🔄 Reconnecting... (${attempt})`),
  onError: (error) => console.error('❗ Error:', error)
});
```

### Performance Issues

```typescript
// Increase throttling for state updates
const config = {
  // ... other config
  stateUpdateThrottle: 1000, // Update at most once per second
};

// Reduce queue size
const config = {
  // ... other config
  maxQueueSize: 100,
};
```

## Contributing

Contributions are welcome! Please see our contributing guidelines for more details.

## License

MIT License - see LICENSE file for details.