# React 18 Concurrent Rendering Support

This document describes the React 18 concurrent rendering safety features implemented in rough-native's React hooks.

## 🚀 Overview

React 18 introduced concurrent rendering features that can cause **tearing** and **inconsistent state** in hooks that manage external state. Our implementation uses `useSyncExternalStore` to ensure visual consistency during concurrent updates.

## ⚡ Key Features

### Concurrent-Safe Instance Management
```typescript
// ✅ Concurrent-safe rough instance creation
const rough = useRough(config); // No tearing during config updates
```

### Cached Shape Generation
```typescript
// ✅ Concurrent-safe shape caching
const shape = useRoughShape('polygon', points, options); // Consistent snapshots
```

### Batch Processing Safety
```typescript
// ✅ Concurrent-safe batch rendering
const shapes = useRoughShapes(shapeDefinitions); // Atomic batch updates
```

## 🏗️ Architecture

### RoughInstanceStore
Manages RoughReactNativeSVG instances with concurrent safety:
- **Immutable snapshots** prevent tearing
- **Subscriber pattern** for consistent updates
- **Automatic cleanup** prevents memory leaks

```typescript
class RoughInstanceStore {
  private instances = new Map<string, RoughReactNativeSVG>();
  private listeners = new Set<() => void>();

  getSnapshot(): Map<string, RoughReactNativeSVG> {
    // Return immutable snapshot for concurrent safety
    return new Map(this.instances);
  }

  subscribe(callback: () => void): () => void {
    this.listeners.add(callback);
    return () => this.listeners.delete(callback);
  }
}
```

### ShapeGenerationStore
Manages shape generation with caching and concurrent safety:
- **Cached results** prevent duplicate work
- **Pending generation tracking** avoids race conditions
- **Error caching** prevents retry storms

```typescript
class ShapeGenerationStore {
  private cache = new Map<string, any>();
  private pendingGenerations = new Set<string>();

  generateShape(key: string, generator: () => any): any {
    // Check cache first
    if (this.cache.has(key)) {
      return this.cache.get(key);
    }

    // Prevent duplicate generation
    if (this.pendingGenerations.has(key)) {
      return null; // Still generating
    }

    // Generate and cache result
    this.pendingGenerations.add(key);
    const result = generator();
    this.cache.set(key, result);
    this.pendingGenerations.delete(key);
    return result;
  }
}
```

## 🔧 Concurrent Hook Implementation

### useRough with useSyncExternalStore
```typescript
export function useRough(config?: Config): RoughReactNativeSVG {
  const stableConfig = useDeepMemo(config, [config]);

  // Concurrent-safe external store subscription
  const storeSnapshot = useSyncExternalStore(
    roughStore.subscribe.bind(roughStore),
    roughStore.getSnapshot.bind(roughStore),
    roughStore.getSnapshot.bind(roughStore) // SSR snapshot
  );

  const rough = useMemo(() => {
    if (!instanceIdRef.current) {
      instanceIdRef.current = roughStore.createInstance(stableConfig);
    } else {
      roughStore.updateInstance(instanceIdRef.current, stableConfig);
    }
    return roughStore.getInstance(instanceIdRef.current);
  }, [stableConfig, storeSnapshot]);

  return rough;
}
```

### useRoughShape with Concurrent Caching
```typescript
export function useRoughShape<T extends keyof ShapeParams>(
  shapeType: T,
  params: ShapeParams[T],
  options?: Options
) {
  const rough = useRough();
  const shapeKey = useMemo(() => 
    `${shapeType}-${JSON.stringify(params)}-${JSON.stringify(options)}`
  , [shapeType, params, options]);

  // Concurrent-safe shape generation
  const storeSnapshot = useSyncExternalStore(
    shapeStore.subscribe.bind(shapeStore),
    shapeStore.getSnapshot.bind(shapeStore),
    shapeStore.getSnapshot.bind(shapeStore)
  );

  const shape = useMemo(() => {
    return shapeStore.generateShape(shapeKey, () => {
      // Shape generation logic
      return rough[shapeType](params, options);
    });
  }, [shapeKey, rough, storeSnapshot]);

  return shape || { props: {}, children: [] };
}
```

## 🎯 Benefits

### Visual Consistency
- **No tearing** during concurrent updates
- **Consistent snapshots** across component tree
- **Atomic updates** for batch operations

### Performance
- **Cached results** prevent duplicate work
- **Efficient subscriptions** minimize re-renders
- **Smart caching** with automatic cleanup

### Developer Experience
- **Transparent usage** - works like regular hooks
- **Debug utilities** for monitoring performance
- **Error handling** with graceful degradation

## 🔍 Debugging Tools

### Performance Monitoring
```typescript
import { debugUtils } from 'rough-native';

// Get cache statistics
const deepEqualStats = debugUtils.getDeepEqualStats();
console.log(`Hit rate: ${deepEqualStats.hitRate * 100}%`);

// Monitor instance count
const instanceCount = debugUtils.getRoughInstanceCount();
console.log(`Active instances: ${instanceCount}`);

// Check shape cache size
const cacheSize = debugUtils.getShapeCacheSize();
console.log(`Cached shapes: ${cacheSize}`);
```

### Cache Management
```typescript
// Clear all caches for testing
debugUtils.clearAllCaches();

// Clear specific caches
debugUtils.clearRoughInstances();
debugUtils.clearShapeCache();
debugUtils.clearDeepEqualCache();
```

## 🧪 Usage Examples

### Concurrent Updates with useTransition
```tsx
import React, { useTransition, startTransition } from 'react';
import { useRoughShape } from 'rough-native';

function ConcurrentShapeDemo() {
  const [isPending, startTransition] = useTransition();
  const [complexity, setComplexity] = useState(5);

  // ✅ Concurrent-safe shape generation
  const shape = useRoughShape('polygon', generatePoints(complexity));

  const handleComplexityChange = () => {
    startTransition(() => {
      setComplexity(c => c * 2); // Large update marked as transition
    });
  };

  return (
    <View>
      <Button title="Increase Complexity" onPress={handleComplexityChange} />
      {isPending ? <Text>Updating...</Text> : null}
      <Svg>{/* Render shape without tearing */}</Svg>
    </View>
  );
}
```

### Batch Concurrent Processing
```tsx
function ConcurrentBatchDemo() {
  const [shapes, setShapes] = useState(initialShapes);
  
  // ✅ Concurrent-safe batch processing
  const renderedShapes = useRoughShapes(shapes);

  const handleBatchUpdate = () => {
    startTransition(() => {
      setShapes(generateComplexShapes()); // Large batch update
    });
  };

  return <Svg>{/* All shapes render consistently */}</Svg>;
}
```

## 🔒 Concurrent Safety Guarantees

### Tearing Prevention
- **Immutable snapshots** ensure visual consistency
- **Synchronized updates** across component tree
- **Atomic state changes** prevent partial updates

### Race Condition Protection
- **Pending generation tracking** prevents duplicate work
- **Cache consistency** during concurrent access
- **Error isolation** prevents cascade failures

### Memory Safety
- **WeakMap usage** allows garbage collection
- **Automatic cleanup** on component unmount
- **Bounded caches** prevent memory bloat

The concurrent rendering implementation ensures that rough-native hooks work seamlessly with React 18's concurrent features while maintaining excellent performance and visual consistency.