mixpanel-react-native
Version:
Official React Native Tracking Library for Mixpanel Analytics
131 lines (100 loc) • 3.3 kB
Markdown
# Pattern Evolution Analysis - 2025-05-30
## Evolved Patterns
### 1. UUID Generation Pattern Evolution
**Pattern Lifecycle Stage**: 🌿 Growing
**Previously Documented**:
```javascript
this._identity[token].deviceId = uuid.v4();
```
**Evolved Pattern**:
```javascript
try {
this._identity[token].deviceId = randomUUID();
} catch (e) {
this._identity[token].deviceId = uuid.v4();
}
```
**Evolution Notes**:
- Adopted try-catch pattern for Expo compatibility
- Prefers expo-crypto's randomUUID() when available
- Gracefully falls back to uuid.v4() for non-Expo environments
- Pattern is in "Growing" stage - new code uses this approach
### 2. Storage Instance Initialization
**Pattern Lifecycle Stage**: 🌳 Mature
**Previously Documented**:
```javascript
MixpanelPersistent.getInstance(storage);
```
**Evolved Pattern**:
```javascript
MixpanelPersistent.getInstance(storage, token);
```
**Evolution Context**:
- Improved token-scoped initialization
- Better isolation between multiple Mixpanel instances
- Ensures proper initialization completion per token
### 3. Conditional Property Inclusion
**Pattern Lifecycle Stage**: 🌱 Emerging
**New Pattern**:
```javascript
const profileData = {
$token: token,
$time: Date.now(),
...action,
...(distinctId != null && { $distinct_id: distinctId }),
...(deviceId != null && { $device_id: deviceId }),
...(userId != null && { $user_id: userId }),
};
```
**Pattern Context**:
- Prevents sending null/undefined values to API
- Uses modern JavaScript conditional spread syntax
- Cleaner than previous approach of always including properties
### 4. Queue Identity Management
**Pattern Lifecycle Stage**: 🌿 Growing
**New Addition**:
```javascript
await this.core.identifyUserQueue(token);
```
**Pattern Context**:
- Ensures user queue is properly updated after identification
- Addresses issue where engage events were sent before identification
- Part of improved identity management flow
### 5. Storage Module Resolution
**Pattern Lifecycle Stage**: 🌳 Mature
**Enhanced Pattern**:
```javascript
const storageModule = require("@react-native-async-storage/async-storage");
if (storageModule.default) {
this.storage = storageModule.default
} else {
this.storage = storageModule
}
```
**Evolution Notes**:
- Handles both ES6 default exports and CommonJS exports
- More robust module resolution
- Prevents issues with different bundler configurations
## New Helper Methods
### Identity Check Helper
```javascript
isIdentified(token) {
return Boolean(this.getUserId(token));
}
```
**Pattern**: Convenience method for common checks
**Follows**: Existing helper method patterns in codebase
## Configuration Pattern Extension
### Gzip Compression Support
Added throughout the stack as optional configuration:
- API level: `init(..., useGzipCompression = false)`
- Native iOS: Additional parameter in initialize
- Native Android: Additional parameter handling
- Maintains backward compatibility with default false
## Import Formatting Evolution
**Previous**: Inconsistent spacing
**Current**: Consistent destructuring imports with spaces
```javascript
import { MixpanelCore } from "./mixpanel-core";
```
This appears to be from automated formatting (prettier/eslint), indicating improved code quality tooling.