UNPKG

mixpanel-react-native

Version:

Official React Native Tracking Library for Mixpanel Analytics

131 lines (100 loc) 3.3 kB
# 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.