mixpanel-react-native
Version:
Official React Native Tracking Library for Mixpanel Analytics
207 lines (162 loc) • 7.86 kB
Markdown
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
### Testing
- Run all tests: `npm test`
- Run specific test: `npm test -- path/to/test.js`
- Tests are located in `__tests__/` directory
- Run tests with coverage: `npm test -- --coverage`
### Development
- This is a library package with no build/dev server commands
- For testing changes, use the sample apps in `Samples/` directory
- Native changes require: `cd ios && pod install` (iOS) or gradle sync (Android)
### Debugging
- Enable logging: `mixpanel.setLoggingEnabled(true)`
- All logs prefixed with `[Mixpanel]` for easy filtering
- See `claude/workflows/03-debugging-issues.md` for comprehensive debugging guide
## Discovered Conventions
### Code Style & Patterns
- **File naming**: kebab-case (`mixpanel-core.js`, `mixpanel-queue.js`)
- **Variables**: camelCase for standard vars, SCREAMING_SNAKE_CASE for constants
- **Functions**: verb-first naming (`initialize`, `track`, `flush`)
- **Imports**: External deps first, then internal modules grouped by purpose (with consistent spacing)
- **Error handling**: Comprehensive input validation with Helper classes
- **Logging**: Token-scoped conditional logging throughout
- **UUID Generation** [Updated: 2025-05-30]: Try expo-crypto first, fallback to uuid.v4()
### API Design Philosophy
- **Graceful degradation**: Native → JavaScript fallback strategy
- **Defensive programming**: Validate all inputs, handle all errors
- **Silent failures**: Storage/network errors don't crash the app
- **Token isolation**: All state scoped by token for multi-project support
### Key Architectural Patterns
- **Factory functions**: Core modules use dependency injection
- **Singleton pattern**: Shared resources (config, storage) use singletons
- **Write-through caching**: Memory cache backed by persistent storage
- **Queue-based processing**: Async event batching with retry logic
## Critical Workflows
### 1. Adding New Features (`claude/workflows/01-adding-new-features.md`)
```bash
# Essential steps for new features:
1. Design API with input validation (StringHelper/ObjectHelper)
2. Implement iOS native version with @objc decorator
3. Implement Android native version with @ReactMethod
4. Add JavaScript fallback implementation
5. Write comprehensive tests for both modes
6. Update TypeScript definitions and documentation
```
### 2. Testing Changes (`claude/workflows/02-testing-changes.md`)
```bash
# Test both implementation modes:
npm test # Run full test suite
npm test -- __tests__/core.test.js # Test specific module
# Test in sample apps:
cd Samples/SimpleMixpanel && npm install && npx react-native run-ios
```
### 3. Debugging Issues (`claude/workflows/03-debugging-issues.md`)
```javascript
// Quick diagnostic script:
const debugImplementationMode = () => {
console.log('Native available:', !!NativeModules.MixpanelReactNative);
console.log('Using:', mixpanel.mixpanelImpl === MixpanelReactNative ? 'Native' : 'JS');
};
```
## Quick Reference
### Most-Used File Locations
- **Main API**: `index.js` (public interface with validation)
- **JS Implementation**: `javascript/mixpanel-main.js`
- **Core Logic**: `javascript/mixpanel-core.js`
- **Queue Management**: `javascript/mixpanel-queue.js`
- **Network Layer**: `javascript/mixpanel-network.js`
- **Storage Layer**: `javascript/mixpanel-storage.js`
- **iOS Native**: `ios/MixpanelReactNative.swift`
- **Android Native**: `android/src/main/java/com/mixpanel/reactnative/MixpanelReactNativeModule.java`
### Common Commands
```bash
# After native changes:
cd ios && pod install # iOS
cd android && ./gradlew clean # Android
# Testing specific modes:
new Mixpanel(token, true, true) # Force native mode
new Mixpanel(token, true, false) # Force JavaScript mode
# Initialize with gzip compression [Updated: 2025-05-30]:
await mixpanel.init(false, {}, "https://api.mixpanel.com", true)
# Debug storage:
AsyncStorage.getAllKeys().then(console.log)
# Manual flush for testing:
mixpanel.flush()
# Check if user is identified [Updated: 2025-05-30]:
mixpanel.mixpanelImpl.mixpanelPersistent.isIdentified(token)
```
### Key Constants & Patterns
```javascript
// Storage key pattern:
`MIXPANEL_${token}_${type}_${field}`
// Queue types:
MixpanelType.EVENTS // "/track/"
MixpanelType.USER // "/engage/"
MixpanelType.GROUPS // "/groups/"
// Error handling pattern:
if (!StringHelper.isValid(param)) {
StringHelper.raiseError(PARAM_NAME);
}
// Conditional property inclusion [Updated: 2025-05-30]:
const data = {
...requiredProps,
...(optionalValue != null && { optionalKey: optionalValue })
};
```
## Architecture Context
For deeper architecture understanding, consult:
- `claude/context-map.md` - Guide to knowledge architecture
- `claude/architecture/system-design.md` - Detailed system design with diagrams
- `claude/discovered-patterns.md` - Comprehensive coding patterns
- `claude/codebase-map.md` - File organization and responsibilities
## AI Assistant Ecosystem
This project maintains a three-layer AI configuration system:
1. **Knowledge Layer** (Claude Code Context)
- CLAUDE.md: Primary project reference
- `claude/`: Discovered patterns, architecture, workflows
2. **Behavioral Layer** (Cursor Rules)
- `.cursor/rules/`: MDC rules for active code generation guidance
- Available to Claude Code via file reading when deeper context needed
3. **Persistent Layer** (Copilot Instructions)
- `.github/copilot-instructions.md`: Core universal patterns (<500 lines)
- `.github/instructions/`: Specialized task-specific instructions
- `.github/prompts/`: Reusable prompt templates for complex operations
Claude Code can access all layers for comprehensive understanding.
Last ecosystem update: 2025-05-30
Next maintenance due: 2025-08-28
For maintenance: Run `/user:ai-ecosystem-maintenance`
## Generated Context (Original)
### Dual Implementation Strategy
The library operates in two modes:
1. **Native Mode** (default): Uses native iOS/Android modules for better performance
2. **JavaScript Mode**: Pure JS implementation for Expo and React Native Web support
Mode selection happens automatically based on platform capabilities.
### Core Components
**Entry Points:**
- `index.js` - Main entry exporting Mixpanel, People, and MixpanelGroup classes
- `index.d.ts` - TypeScript definitions
**Native Modules:**
- `ios/MixpanelReactNative.swift` - iOS implementation using Mixpanel Swift SDK
- `android/src/main/java/com/mixpanel/reactnative/MixpanelReactNativeModule.java` - Android implementation
**JavaScript Implementation (`javascript/` directory):**
- `mixpanel-main.js` - JS mode entry point, implements full Mixpanel API
- `mixpanel-core.js` - Core tracking logic shared between modes
- `mixpanel-queue.js` - Event queue management with automatic flushing
- `mixpanel-network.js` - HTTP request handling with retry logic
- `mixpanel-storage.js` - Abstraction over AsyncStorage for persistence
### Data Flow
1. API calls go through `index.js` which routes to native module or JS implementation
2. Events are queued (in-memory + persistent storage)
3. Queues flush automatically every 10s (JS) or 60s (native)
4. Failed requests retry with exponential backoff
### Key Patterns
- **Token-based instances**: Multiple Mixpanel projects supported via different tokens
- **Persistent state**: Super properties, user IDs, and queues survive app restarts
- **Automatic properties**: Device info, OS version, etc. added automatically
- **GDPR compliance**: Built-in opt-out and data deletion methods
## Testing Guidelines
- Mock AsyncStorage and React Native modules are pre-configured
- Test both native and JS modes when making changes
- Use sample apps to verify integration works correctly