@magicpixel/rn-mp-client-sdk 1.13.21 → 1.13.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,16 +14,55 @@ npm install @magicpixel/rn-mp-client-sdk
14
14
  npm install react-native @react-native-async-storage/async-storage
15
15
  ```
16
16
 
17
- ### For Bare React Native (Optional)
17
+ ### For Bare React Native
18
18
 
19
- For enhanced device info detection:
19
+ Bare React Native apps require additional setup:
20
20
 
21
+ #### 1. Install Required Dependencies
22
+
23
+ ```sh
24
+ npm install react-native-get-random-values react-native-device-info
25
+ ```
26
+
27
+ #### 2. Link Native Modules (Required)
28
+
29
+ **iOS:**
21
30
  ```sh
22
- npm install react-native-device-info
23
- npx pod-install
31
+ cd ios && pod install && cd ..
32
+ ```
33
+
34
+ **Android:** Native modules are auto-linked via Gradle.
35
+
36
+ > ⚠️ **Important:** After running `pod install`, you must fully restart the app:
37
+ > 1. Kill the app in the simulator/device
38
+ > 2. Stop Metro bundler (`Ctrl+C`)
39
+ > 3. Restart Metro (`npx react-native start`)
40
+ > 4. Rebuild and launch the app
41
+ >
42
+ > Simply reloading Metro is not sufficient - the native binary must be rebuilt.
43
+
44
+ #### 3. Add Polyfill Import (Required)
45
+
46
+ Add this import at the very top of your app's entry file (`index.js`), **before any other imports**:
47
+
48
+ ```javascript
49
+ import 'react-native-get-random-values'; // Must be first import!
50
+
51
+ import {AppRegistry} from 'react-native';
52
+ import App from './App';
53
+ import {name as appName} from './app.json';
54
+
55
+ AppRegistry.registerComponent(appName, () => App);
24
56
  ```
25
57
 
26
- > **Note**: For Expo apps, device info is automatically detected using Expo modules. No additional setup required.
58
+ > ⚠️ **Without this setup, you will see the error:**
59
+ > ```
60
+ > MagicPixel SDK initialization failed: Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'RNGetRandomValues' could not be found.
61
+ > ```
62
+
63
+ The SDK uses ULID for generating unique identifiers, which requires `crypto.getRandomValues()`. This polyfill must be loaded before any other code runs.
64
+
65
+ > **Note**: For Expo managed apps, no additional setup is required - the polyfill is handled automatically.
27
66
 
28
67
  ## Quick Start
29
68
 
@@ -12,40 +12,55 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
12
12
  /**
13
13
  * Helper class to automatically detect device and app information
14
14
  * Supports both Expo and bare React Native:
15
- * 1. Tries Expo modules first (works in Expo Go)
16
- * 2. Falls back to react-native-device-info (for bare RN)
15
+ * 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)
16
+ * 2. Falls back to Expo modules (for Expo Go where native modules don't work)
17
17
  * 3. Returns safe defaults if neither is available
18
18
  */
19
19
  class DeviceInfoHelper {
20
20
  /**
21
- * Try to load Expo modules and react-native-device-info
22
- * This uses dynamic imports to avoid errors when modules aren't available
21
+ * Try to load react-native-device-info first, then Expo modules
22
+ * Uses console.log during init to avoid Logger dependency issues if module loading fails
23
23
  */
24
24
  static async initialize() {
25
25
  if (this.initialized) return;
26
26
 
27
- // Try to load Expo modules first (works in Expo Go)
27
+ // FIRST: Try react-native-device-info (preferred - works in bare RN and Expo custom builds)
28
+ // This is a direct dependency of the SDK, so it should always be available except in Expo Go
28
29
  try {
29
30
  // eslint-disable-next-line @typescript-eslint/no-var-requires
30
- this.expoApplication = require('expo-application');
31
- // eslint-disable-next-line @typescript-eslint/no-var-requires
32
- this.expoDevice = require('expo-device');
33
- // eslint-disable-next-line @typescript-eslint/no-var-requires
34
- this.expoConstants = require('expo-constants').default;
35
- _logger.Logger.logDbg('Using Expo modules for device info');
31
+ const rnDeviceInfo = require('react-native-device-info');
32
+ // Validate the module is actually loaded and functional
33
+ if (rnDeviceInfo && typeof (rnDeviceInfo.default || rnDeviceInfo).getVersion === 'function') {
34
+ this.deviceInfo = rnDeviceInfo.default || rnDeviceInfo;
35
+ this.initialized = true;
36
+ // Use console.log to avoid any Logger issues during early init
37
+ console.log('[MagicPixel DeviceInfoHelper] Using react-native-device-info');
38
+ return;
39
+ }
36
40
  } catch (error) {
37
- _logger.Logger.logDbg('Expo modules not available, will try react-native-device-info');
41
+ // react-native-device-info not available (likely Expo Go)
42
+ console.log('[MagicPixel DeviceInfoHelper] react-native-device-info not available, trying Expo modules');
38
43
  }
39
44
 
40
- // Fall back to react-native-device-info (for bare RN)
41
- if (!this.expoApplication) {
42
- try {
43
- // eslint-disable-next-line @typescript-eslint/no-var-requires
44
- this.deviceInfo = require('react-native-device-info').default;
45
- _logger.Logger.logDbg('Using react-native-device-info for device info');
46
- } catch (error) {
47
- _logger.Logger.logError('Neither Expo modules nor react-native-device-info available:', error);
45
+ // SECOND: Fall back to Expo modules (for Expo Go where native modules don't work)
46
+ try {
47
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
48
+ const expoApp = require('expo-application');
49
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
50
+ const expoDevice = require('expo-device');
51
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
52
+ const expoConst = require('expo-constants');
53
+
54
+ // Validate modules are actually loaded (not undefined placeholders from Metro)
55
+ if (expoApp && expoDevice && expoConst && typeof expoApp.nativeApplicationVersion !== 'undefined') {
56
+ this.expoApplication = expoApp;
57
+ this.expoDevice = expoDevice;
58
+ this.expoConstants = expoConst.default || expoConst;
59
+ console.log('[MagicPixel DeviceInfoHelper] Using Expo modules');
48
60
  }
61
+ } catch (error) {
62
+ // Expo modules not available
63
+ console.log('[MagicPixel DeviceInfoHelper] Expo modules not available, using safe defaults');
49
64
  }
50
65
  this.initialized = true;
51
66
  }
@@ -57,20 +72,21 @@ class DeviceInfoHelper {
57
72
  static async getAppInfo() {
58
73
  await this.initialize();
59
74
  try {
60
- // Try Expo modules first
61
- if (this.expoApplication && this.expoDevice) {
62
- return await this.getAppInfoFromExpo();
63
- }
64
-
65
- // Fall back to react-native-device-info
75
+ // Use react-native-device-info if available (preferred)
66
76
  if (this.deviceInfo) {
67
77
  return await this.getAppInfoFromDeviceInfo();
68
78
  }
69
79
 
80
+ // Fall back to Expo modules (for Expo Go)
81
+ if (this.expoApplication && this.expoDevice) {
82
+ return await this.getAppInfoFromExpo();
83
+ }
84
+
70
85
  // Return safe fallback values
71
86
  return this.getSafeDefaults();
72
87
  } catch (error) {
73
- _logger.Logger.logError('Error getting device info:', error);
88
+ // Use console.log here as well to be safe
89
+ console.error('[MagicPixel DeviceInfoHelper] Error getting device info:', error);
74
90
  return this.getSafeDefaults();
75
91
  }
76
92
  }
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_logger","_defineProperty","e","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","DeviceInfoHelper","initialize","initialized","expoApplication","expoDevice","expoConstants","default","Logger","logDbg","error","deviceInfo","logError","getAppInfo","getAppInfoFromExpo","getAppInfoFromDeviceInfo","getSafeDefaults","_Platform$Version","version","nativeApplicationVersion","buildNumber","nativeBuildVersion","packageName","applicationId","app_version","build_number","package_name","device_model_name","modelName","device_manufacturer","manufacturer","device_id","sessionId","os_name","Platform","OS","os_version","osVersion","Version","toString","is_tablet","deviceType","is_emulator","isDevice","uniqueId","bundleId","Promise","all","getVersion","getBuildNumber","getUniqueId","getBundleId","getModel","getManufacturerSync","getSystemVersion","isTablet","isEmulator","_Platform$Version2","getFormattedAppVersion","info","exports"],"sources":["device-info-helper.ts"],"sourcesContent":["import { Platform } from 'react-native';\nimport { Logger } from './logger';\n\ninterface DeviceAppInfo {\n app_version: string;\n build_number: string;\n package_name: string;\n device_model_name: string;\n device_manufacturer: string;\n device_id: string;\n os_name: string;\n os_version: string;\n is_tablet: boolean;\n is_emulator: boolean;\n}\n\n/**\n * Helper class to automatically detect device and app information\n * Supports both Expo and bare React Native:\n * 1. Tries Expo modules first (works in Expo Go)\n * 2. Falls back to react-native-device-info (for bare RN)\n * 3. Returns safe defaults if neither is available\n */\nexport class DeviceInfoHelper {\n private static expoApplication: any = null;\n private static expoDevice: any = null;\n private static expoConstants: any = null;\n private static deviceInfo: any = null;\n private static initialized = false;\n\n /**\n * Try to load Expo modules and react-native-device-info\n * This uses dynamic imports to avoid errors when modules aren't available\n */\n private static async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Try to load Expo modules first (works in Expo Go)\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoApplication = require('expo-application');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoDevice = require('expo-device');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoConstants = require('expo-constants').default;\n Logger.logDbg('Using Expo modules for device info');\n } catch (error) {\n Logger.logDbg(\n 'Expo modules not available, will try react-native-device-info'\n );\n }\n\n // Fall back to react-native-device-info (for bare RN)\n if (!this.expoApplication) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.deviceInfo = require('react-native-device-info').default;\n Logger.logDbg('Using react-native-device-info for device info');\n } catch (error) {\n Logger.logError(\n 'Neither Expo modules nor react-native-device-info available:',\n error\n );\n }\n }\n\n this.initialized = true;\n }\n\n /**\n * Get comprehensive app and device information\n * All methods are async-safe and handle errors gracefully\n */\n static async getAppInfo(): Promise<DeviceAppInfo> {\n await this.initialize();\n\n try {\n // Try Expo modules first\n if (this.expoApplication && this.expoDevice) {\n return await this.getAppInfoFromExpo();\n }\n\n // Fall back to react-native-device-info\n if (this.deviceInfo) {\n return await this.getAppInfoFromDeviceInfo();\n }\n\n // Return safe fallback values\n return this.getSafeDefaults();\n } catch (error) {\n Logger.logError('Error getting device info:', error);\n return this.getSafeDefaults();\n }\n }\n\n /**\n * Get device info using Expo modules (works in Expo Go)\n */\n private static async getAppInfoFromExpo(): Promise<DeviceAppInfo> {\n const version = this.expoApplication.nativeApplicationVersion || 'unknown';\n const buildNumber = this.expoApplication.nativeBuildVersion || 'unknown';\n const packageName = this.expoApplication.applicationId || 'unknown';\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: packageName,\n\n // Device information\n device_model_name: this.expoDevice.modelName || 'unknown',\n device_manufacturer: this.expoDevice.manufacturer || 'unknown',\n device_id: this.expoConstants.sessionId || 'unknown',\n\n // OS information\n os_name: Platform.OS,\n os_version:\n this.expoDevice.osVersion || Platform.Version?.toString() || 'unknown',\n\n // Additional useful info\n // DeviceType enum: UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4\n is_tablet: this.expoDevice.deviceType === 2, // DeviceType.TABLET = 2\n is_emulator: !this.expoDevice.isDevice,\n };\n }\n\n /**\n * Get device info using react-native-device-info (for bare RN)\n */\n private static async getAppInfoFromDeviceInfo(): Promise<DeviceAppInfo> {\n const [version, buildNumber, uniqueId, bundleId] = await Promise.all([\n this.deviceInfo.getVersion(),\n this.deviceInfo.getBuildNumber(),\n this.deviceInfo.getUniqueId(),\n this.deviceInfo.getBundleId(),\n ]);\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: bundleId,\n\n // Device information\n device_model_name: this.deviceInfo.getModel(),\n device_manufacturer: this.deviceInfo.getManufacturerSync(),\n device_id: uniqueId,\n\n // OS information\n os_name: Platform.OS,\n os_version: this.deviceInfo.getSystemVersion(),\n\n // Additional useful info\n is_tablet: this.deviceInfo.isTablet(),\n is_emulator: await this.deviceInfo.isEmulator(),\n };\n }\n\n /**\n * Safe default values when no device info library is available\n */\n private static getSafeDefaults(): DeviceAppInfo {\n return {\n app_version: 'unknown',\n build_number: 'unknown',\n package_name: 'unknown',\n device_model_name: 'unknown',\n device_manufacturer: 'unknown',\n device_id: 'unknown',\n os_name: Platform.OS,\n os_version: Platform.Version?.toString() || 'unknown',\n is_tablet: false,\n is_emulator: false,\n };\n }\n\n /**\n * Get app version in format: \"1.0.0 (123)\"\n * Combines version and build number for better tracking\n */\n static async getFormattedAppVersion(): Promise<string> {\n try {\n const info = await this.getAppInfo();\n return `${info.app_version} (${info.build_number})`;\n } catch (error) {\n Logger.logError('Error getting formatted app version:', error);\n return 'unknown';\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_logger","_defineProperty","e","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","DeviceInfoHelper","initialize","initialized","rnDeviceInfo","default","getVersion","deviceInfo","console","log","error","expoApp","expoDevice","expoConst","nativeApplicationVersion","expoApplication","expoConstants","getAppInfo","getAppInfoFromDeviceInfo","getAppInfoFromExpo","getSafeDefaults","_Platform$Version","version","buildNumber","nativeBuildVersion","packageName","applicationId","app_version","build_number","package_name","device_model_name","modelName","device_manufacturer","manufacturer","device_id","sessionId","os_name","Platform","OS","os_version","osVersion","Version","toString","is_tablet","deviceType","is_emulator","isDevice","uniqueId","bundleId","Promise","all","getBuildNumber","getUniqueId","getBundleId","getModel","getManufacturerSync","getSystemVersion","isTablet","isEmulator","_Platform$Version2","getFormattedAppVersion","info","Logger","logError","exports"],"sources":["device-info-helper.ts"],"sourcesContent":["import { Platform } from 'react-native';\nimport { Logger } from './logger';\n\ninterface DeviceAppInfo {\n app_version: string;\n build_number: string;\n package_name: string;\n device_model_name: string;\n device_manufacturer: string;\n device_id: string;\n os_name: string;\n os_version: string;\n is_tablet: boolean;\n is_emulator: boolean;\n}\n\n/**\n * Helper class to automatically detect device and app information\n * Supports both Expo and bare React Native:\n * 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)\n * 2. Falls back to Expo modules (for Expo Go where native modules don't work)\n * 3. Returns safe defaults if neither is available\n */\nexport class DeviceInfoHelper {\n private static expoApplication: any = null;\n private static expoDevice: any = null;\n private static expoConstants: any = null;\n private static deviceInfo: any = null;\n private static initialized = false;\n\n /**\n * Try to load react-native-device-info first, then Expo modules\n * Uses console.log during init to avoid Logger dependency issues if module loading fails\n */\n private static async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // FIRST: Try react-native-device-info (preferred - works in bare RN and Expo custom builds)\n // This is a direct dependency of the SDK, so it should always be available except in Expo Go\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const rnDeviceInfo = require('react-native-device-info');\n // Validate the module is actually loaded and functional\n if (\n rnDeviceInfo &&\n typeof (rnDeviceInfo.default || rnDeviceInfo).getVersion === 'function'\n ) {\n this.deviceInfo = rnDeviceInfo.default || rnDeviceInfo;\n this.initialized = true;\n // Use console.log to avoid any Logger issues during early init\n console.log(\n '[MagicPixel DeviceInfoHelper] Using react-native-device-info'\n );\n return;\n }\n } catch (error) {\n // react-native-device-info not available (likely Expo Go)\n console.log(\n '[MagicPixel DeviceInfoHelper] react-native-device-info not available, trying Expo modules'\n );\n }\n\n // SECOND: Fall back to Expo modules (for Expo Go where native modules don't work)\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoApp = require('expo-application');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoDevice = require('expo-device');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoConst = require('expo-constants');\n\n // Validate modules are actually loaded (not undefined placeholders from Metro)\n if (\n expoApp &&\n expoDevice &&\n expoConst &&\n typeof expoApp.nativeApplicationVersion !== 'undefined'\n ) {\n this.expoApplication = expoApp;\n this.expoDevice = expoDevice;\n this.expoConstants = expoConst.default || expoConst;\n console.log('[MagicPixel DeviceInfoHelper] Using Expo modules');\n }\n } catch (error) {\n // Expo modules not available\n console.log(\n '[MagicPixel DeviceInfoHelper] Expo modules not available, using safe defaults'\n );\n }\n\n this.initialized = true;\n }\n\n /**\n * Get comprehensive app and device information\n * All methods are async-safe and handle errors gracefully\n */\n static async getAppInfo(): Promise<DeviceAppInfo> {\n await this.initialize();\n\n try {\n // Use react-native-device-info if available (preferred)\n if (this.deviceInfo) {\n return await this.getAppInfoFromDeviceInfo();\n }\n\n // Fall back to Expo modules (for Expo Go)\n if (this.expoApplication && this.expoDevice) {\n return await this.getAppInfoFromExpo();\n }\n\n // Return safe fallback values\n return this.getSafeDefaults();\n } catch (error) {\n // Use console.log here as well to be safe\n console.error('[MagicPixel DeviceInfoHelper] Error getting device info:', error);\n return this.getSafeDefaults();\n }\n }\n\n /**\n * Get device info using Expo modules (works in Expo Go)\n */\n private static async getAppInfoFromExpo(): Promise<DeviceAppInfo> {\n const version = this.expoApplication.nativeApplicationVersion || 'unknown';\n const buildNumber = this.expoApplication.nativeBuildVersion || 'unknown';\n const packageName = this.expoApplication.applicationId || 'unknown';\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: packageName,\n\n // Device information\n device_model_name: this.expoDevice.modelName || 'unknown',\n device_manufacturer: this.expoDevice.manufacturer || 'unknown',\n device_id: this.expoConstants.sessionId || 'unknown',\n\n // OS information\n os_name: Platform.OS,\n os_version:\n this.expoDevice.osVersion || Platform.Version?.toString() || 'unknown',\n\n // Additional useful info\n // DeviceType enum: UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4\n is_tablet: this.expoDevice.deviceType === 2, // DeviceType.TABLET = 2\n is_emulator: !this.expoDevice.isDevice,\n };\n }\n\n /**\n * Get device info using react-native-device-info (for bare RN)\n */\n private static async getAppInfoFromDeviceInfo(): Promise<DeviceAppInfo> {\n const [version, buildNumber, uniqueId, bundleId] = await Promise.all([\n this.deviceInfo.getVersion(),\n this.deviceInfo.getBuildNumber(),\n this.deviceInfo.getUniqueId(),\n this.deviceInfo.getBundleId(),\n ]);\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: bundleId,\n\n // Device information\n device_model_name: this.deviceInfo.getModel(),\n device_manufacturer: this.deviceInfo.getManufacturerSync(),\n device_id: uniqueId,\n\n // OS information\n os_name: Platform.OS,\n os_version: this.deviceInfo.getSystemVersion(),\n\n // Additional useful info\n is_tablet: this.deviceInfo.isTablet(),\n is_emulator: await this.deviceInfo.isEmulator(),\n };\n }\n\n /**\n * Safe default values when no device info library is available\n */\n private static getSafeDefaults(): DeviceAppInfo {\n return {\n app_version: 'unknown',\n build_number: 'unknown',\n package_name: 'unknown',\n device_model_name: 'unknown',\n device_manufacturer: 'unknown',\n device_id: 'unknown',\n os_name: Platform.OS,\n os_version: Platform.Version?.toString() || 'unknown',\n is_tablet: false,\n is_emulator: false,\n };\n }\n\n /**\n * Get app version in format: \"1.0.0 (123)\"\n * Combines version and build number for better tracking\n */\n static async getFormattedAppVersion(): Promise<string> {\n try {\n const info = await this.getAppInfo();\n return `${info.app_version} (${info.build_number})`;\n } catch (error) {\n Logger.logError('Error getting formatted app version:', error);\n return 'unknown';\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=sdk.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["sdk.d.ts"],"sourcesContent":["declare module '@magicpixel/rn-mp-client-sdk' {\n interface InitConfig {\n orgId: string;\n env: 'staging' | 'production';\n projectId: string;\n baseUrl: string;\n logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none';\n eventDeduplicationWindowMs?: number;\n onInitFailure?: (error: Error) => void;\n }\n\n interface UserInfo {\n pid?: string;\n email?: string;\n phone?: string;\n country?: string;\n city?: string;\n state?: string;\n fName?: string;\n lName?: string;\n zip?: string;\n }\n\n interface PageLoadData {\n page_name: string;\n [key: string]: any;\n }\n\n class MagicPixelImpl {\n init(config: InitConfig): void;\n shutdown(): void;\n recordEvent(eventName: string, payload?: Record<string, any>): void;\n recordPageLoad(data: PageLoadData): void;\n setUserInfo(userInfo: UserInfo): void;\n setCustomerInfo(customerInfo: Record<string, any>): void;\n setDeviceInfo(customFields?: Record<string, any>): void;\n setDeepLinkUrl(url: string): void;\n setFirebaseAppInstanceId(id: string): void;\n getDebugId(): Promise<string | null>;\n setDataLayer(data: Record<string, any>): void;\n persistData(key: string, value: any): void;\n clearPersistedData(keys: string[]): void;\n getDataLayer(): Record<string, any>;\n getEventState(): Record<string, any>;\n hasEventHappened(eventName: string): boolean;\n registerEventProcessor(\n eventType: string,\n callback: (event: any) => void\n ): void;\n }\n\n export const MagicPixel: MagicPixelImpl;\n export const MagicPixelEventBus: any;\n}\n"],"mappings":"","ignoreList":[]}
@@ -6,40 +6,55 @@ import { Logger } from './logger';
6
6
  /**
7
7
  * Helper class to automatically detect device and app information
8
8
  * Supports both Expo and bare React Native:
9
- * 1. Tries Expo modules first (works in Expo Go)
10
- * 2. Falls back to react-native-device-info (for bare RN)
9
+ * 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)
10
+ * 2. Falls back to Expo modules (for Expo Go where native modules don't work)
11
11
  * 3. Returns safe defaults if neither is available
12
12
  */
13
13
  export class DeviceInfoHelper {
14
14
  /**
15
- * Try to load Expo modules and react-native-device-info
16
- * This uses dynamic imports to avoid errors when modules aren't available
15
+ * Try to load react-native-device-info first, then Expo modules
16
+ * Uses console.log during init to avoid Logger dependency issues if module loading fails
17
17
  */
18
18
  static async initialize() {
19
19
  if (this.initialized) return;
20
20
 
21
- // Try to load Expo modules first (works in Expo Go)
21
+ // FIRST: Try react-native-device-info (preferred - works in bare RN and Expo custom builds)
22
+ // This is a direct dependency of the SDK, so it should always be available except in Expo Go
22
23
  try {
23
24
  // eslint-disable-next-line @typescript-eslint/no-var-requires
24
- this.expoApplication = require('expo-application');
25
- // eslint-disable-next-line @typescript-eslint/no-var-requires
26
- this.expoDevice = require('expo-device');
27
- // eslint-disable-next-line @typescript-eslint/no-var-requires
28
- this.expoConstants = require('expo-constants').default;
29
- Logger.logDbg('Using Expo modules for device info');
25
+ const rnDeviceInfo = require('react-native-device-info');
26
+ // Validate the module is actually loaded and functional
27
+ if (rnDeviceInfo && typeof (rnDeviceInfo.default || rnDeviceInfo).getVersion === 'function') {
28
+ this.deviceInfo = rnDeviceInfo.default || rnDeviceInfo;
29
+ this.initialized = true;
30
+ // Use console.log to avoid any Logger issues during early init
31
+ console.log('[MagicPixel DeviceInfoHelper] Using react-native-device-info');
32
+ return;
33
+ }
30
34
  } catch (error) {
31
- Logger.logDbg('Expo modules not available, will try react-native-device-info');
35
+ // react-native-device-info not available (likely Expo Go)
36
+ console.log('[MagicPixel DeviceInfoHelper] react-native-device-info not available, trying Expo modules');
32
37
  }
33
38
 
34
- // Fall back to react-native-device-info (for bare RN)
35
- if (!this.expoApplication) {
36
- try {
37
- // eslint-disable-next-line @typescript-eslint/no-var-requires
38
- this.deviceInfo = require('react-native-device-info').default;
39
- Logger.logDbg('Using react-native-device-info for device info');
40
- } catch (error) {
41
- Logger.logError('Neither Expo modules nor react-native-device-info available:', error);
39
+ // SECOND: Fall back to Expo modules (for Expo Go where native modules don't work)
40
+ try {
41
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
42
+ const expoApp = require('expo-application');
43
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
44
+ const expoDevice = require('expo-device');
45
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
46
+ const expoConst = require('expo-constants');
47
+
48
+ // Validate modules are actually loaded (not undefined placeholders from Metro)
49
+ if (expoApp && expoDevice && expoConst && typeof expoApp.nativeApplicationVersion !== 'undefined') {
50
+ this.expoApplication = expoApp;
51
+ this.expoDevice = expoDevice;
52
+ this.expoConstants = expoConst.default || expoConst;
53
+ console.log('[MagicPixel DeviceInfoHelper] Using Expo modules');
42
54
  }
55
+ } catch (error) {
56
+ // Expo modules not available
57
+ console.log('[MagicPixel DeviceInfoHelper] Expo modules not available, using safe defaults');
43
58
  }
44
59
  this.initialized = true;
45
60
  }
@@ -51,20 +66,21 @@ export class DeviceInfoHelper {
51
66
  static async getAppInfo() {
52
67
  await this.initialize();
53
68
  try {
54
- // Try Expo modules first
55
- if (this.expoApplication && this.expoDevice) {
56
- return await this.getAppInfoFromExpo();
57
- }
58
-
59
- // Fall back to react-native-device-info
69
+ // Use react-native-device-info if available (preferred)
60
70
  if (this.deviceInfo) {
61
71
  return await this.getAppInfoFromDeviceInfo();
62
72
  }
63
73
 
74
+ // Fall back to Expo modules (for Expo Go)
75
+ if (this.expoApplication && this.expoDevice) {
76
+ return await this.getAppInfoFromExpo();
77
+ }
78
+
64
79
  // Return safe fallback values
65
80
  return this.getSafeDefaults();
66
81
  } catch (error) {
67
- Logger.logError('Error getting device info:', error);
82
+ // Use console.log here as well to be safe
83
+ console.error('[MagicPixel DeviceInfoHelper] Error getting device info:', error);
68
84
  return this.getSafeDefaults();
69
85
  }
70
86
  }
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","Logger","DeviceInfoHelper","initialize","initialized","expoApplication","require","expoDevice","expoConstants","default","logDbg","error","deviceInfo","logError","getAppInfo","getAppInfoFromExpo","getAppInfoFromDeviceInfo","getSafeDefaults","_Platform$Version","version","nativeApplicationVersion","buildNumber","nativeBuildVersion","packageName","applicationId","app_version","build_number","package_name","device_model_name","modelName","device_manufacturer","manufacturer","device_id","sessionId","os_name","OS","os_version","osVersion","Version","toString","is_tablet","deviceType","is_emulator","isDevice","uniqueId","bundleId","Promise","all","getVersion","getBuildNumber","getUniqueId","getBundleId","getModel","getManufacturerSync","getSystemVersion","isTablet","isEmulator","_Platform$Version2","getFormattedAppVersion","info","_defineProperty"],"sources":["device-info-helper.ts"],"sourcesContent":["import { Platform } from 'react-native';\nimport { Logger } from './logger';\n\ninterface DeviceAppInfo {\n app_version: string;\n build_number: string;\n package_name: string;\n device_model_name: string;\n device_manufacturer: string;\n device_id: string;\n os_name: string;\n os_version: string;\n is_tablet: boolean;\n is_emulator: boolean;\n}\n\n/**\n * Helper class to automatically detect device and app information\n * Supports both Expo and bare React Native:\n * 1. Tries Expo modules first (works in Expo Go)\n * 2. Falls back to react-native-device-info (for bare RN)\n * 3. Returns safe defaults if neither is available\n */\nexport class DeviceInfoHelper {\n private static expoApplication: any = null;\n private static expoDevice: any = null;\n private static expoConstants: any = null;\n private static deviceInfo: any = null;\n private static initialized = false;\n\n /**\n * Try to load Expo modules and react-native-device-info\n * This uses dynamic imports to avoid errors when modules aren't available\n */\n private static async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Try to load Expo modules first (works in Expo Go)\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoApplication = require('expo-application');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoDevice = require('expo-device');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.expoConstants = require('expo-constants').default;\n Logger.logDbg('Using Expo modules for device info');\n } catch (error) {\n Logger.logDbg(\n 'Expo modules not available, will try react-native-device-info'\n );\n }\n\n // Fall back to react-native-device-info (for bare RN)\n if (!this.expoApplication) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.deviceInfo = require('react-native-device-info').default;\n Logger.logDbg('Using react-native-device-info for device info');\n } catch (error) {\n Logger.logError(\n 'Neither Expo modules nor react-native-device-info available:',\n error\n );\n }\n }\n\n this.initialized = true;\n }\n\n /**\n * Get comprehensive app and device information\n * All methods are async-safe and handle errors gracefully\n */\n static async getAppInfo(): Promise<DeviceAppInfo> {\n await this.initialize();\n\n try {\n // Try Expo modules first\n if (this.expoApplication && this.expoDevice) {\n return await this.getAppInfoFromExpo();\n }\n\n // Fall back to react-native-device-info\n if (this.deviceInfo) {\n return await this.getAppInfoFromDeviceInfo();\n }\n\n // Return safe fallback values\n return this.getSafeDefaults();\n } catch (error) {\n Logger.logError('Error getting device info:', error);\n return this.getSafeDefaults();\n }\n }\n\n /**\n * Get device info using Expo modules (works in Expo Go)\n */\n private static async getAppInfoFromExpo(): Promise<DeviceAppInfo> {\n const version = this.expoApplication.nativeApplicationVersion || 'unknown';\n const buildNumber = this.expoApplication.nativeBuildVersion || 'unknown';\n const packageName = this.expoApplication.applicationId || 'unknown';\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: packageName,\n\n // Device information\n device_model_name: this.expoDevice.modelName || 'unknown',\n device_manufacturer: this.expoDevice.manufacturer || 'unknown',\n device_id: this.expoConstants.sessionId || 'unknown',\n\n // OS information\n os_name: Platform.OS,\n os_version:\n this.expoDevice.osVersion || Platform.Version?.toString() || 'unknown',\n\n // Additional useful info\n // DeviceType enum: UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4\n is_tablet: this.expoDevice.deviceType === 2, // DeviceType.TABLET = 2\n is_emulator: !this.expoDevice.isDevice,\n };\n }\n\n /**\n * Get device info using react-native-device-info (for bare RN)\n */\n private static async getAppInfoFromDeviceInfo(): Promise<DeviceAppInfo> {\n const [version, buildNumber, uniqueId, bundleId] = await Promise.all([\n this.deviceInfo.getVersion(),\n this.deviceInfo.getBuildNumber(),\n this.deviceInfo.getUniqueId(),\n this.deviceInfo.getBundleId(),\n ]);\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: bundleId,\n\n // Device information\n device_model_name: this.deviceInfo.getModel(),\n device_manufacturer: this.deviceInfo.getManufacturerSync(),\n device_id: uniqueId,\n\n // OS information\n os_name: Platform.OS,\n os_version: this.deviceInfo.getSystemVersion(),\n\n // Additional useful info\n is_tablet: this.deviceInfo.isTablet(),\n is_emulator: await this.deviceInfo.isEmulator(),\n };\n }\n\n /**\n * Safe default values when no device info library is available\n */\n private static getSafeDefaults(): DeviceAppInfo {\n return {\n app_version: 'unknown',\n build_number: 'unknown',\n package_name: 'unknown',\n device_model_name: 'unknown',\n device_manufacturer: 'unknown',\n device_id: 'unknown',\n os_name: Platform.OS,\n os_version: Platform.Version?.toString() || 'unknown',\n is_tablet: false,\n is_emulator: false,\n };\n }\n\n /**\n * Get app version in format: \"1.0.0 (123)\"\n * Combines version and build number for better tracking\n */\n static async getFormattedAppVersion(): Promise<string> {\n try {\n const info = await this.getAppInfo();\n return `${info.app_version} (${info.build_number})`;\n } catch (error) {\n Logger.logError('Error getting formatted app version:', error);\n return 'unknown';\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["Platform","Logger","DeviceInfoHelper","initialize","initialized","rnDeviceInfo","require","default","getVersion","deviceInfo","console","log","error","expoApp","expoDevice","expoConst","nativeApplicationVersion","expoApplication","expoConstants","getAppInfo","getAppInfoFromDeviceInfo","getAppInfoFromExpo","getSafeDefaults","_Platform$Version","version","buildNumber","nativeBuildVersion","packageName","applicationId","app_version","build_number","package_name","device_model_name","modelName","device_manufacturer","manufacturer","device_id","sessionId","os_name","OS","os_version","osVersion","Version","toString","is_tablet","deviceType","is_emulator","isDevice","uniqueId","bundleId","Promise","all","getBuildNumber","getUniqueId","getBundleId","getModel","getManufacturerSync","getSystemVersion","isTablet","isEmulator","_Platform$Version2","getFormattedAppVersion","info","logError","_defineProperty"],"sources":["device-info-helper.ts"],"sourcesContent":["import { Platform } from 'react-native';\nimport { Logger } from './logger';\n\ninterface DeviceAppInfo {\n app_version: string;\n build_number: string;\n package_name: string;\n device_model_name: string;\n device_manufacturer: string;\n device_id: string;\n os_name: string;\n os_version: string;\n is_tablet: boolean;\n is_emulator: boolean;\n}\n\n/**\n * Helper class to automatically detect device and app information\n * Supports both Expo and bare React Native:\n * 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)\n * 2. Falls back to Expo modules (for Expo Go where native modules don't work)\n * 3. Returns safe defaults if neither is available\n */\nexport class DeviceInfoHelper {\n private static expoApplication: any = null;\n private static expoDevice: any = null;\n private static expoConstants: any = null;\n private static deviceInfo: any = null;\n private static initialized = false;\n\n /**\n * Try to load react-native-device-info first, then Expo modules\n * Uses console.log during init to avoid Logger dependency issues if module loading fails\n */\n private static async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // FIRST: Try react-native-device-info (preferred - works in bare RN and Expo custom builds)\n // This is a direct dependency of the SDK, so it should always be available except in Expo Go\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const rnDeviceInfo = require('react-native-device-info');\n // Validate the module is actually loaded and functional\n if (\n rnDeviceInfo &&\n typeof (rnDeviceInfo.default || rnDeviceInfo).getVersion === 'function'\n ) {\n this.deviceInfo = rnDeviceInfo.default || rnDeviceInfo;\n this.initialized = true;\n // Use console.log to avoid any Logger issues during early init\n console.log(\n '[MagicPixel DeviceInfoHelper] Using react-native-device-info'\n );\n return;\n }\n } catch (error) {\n // react-native-device-info not available (likely Expo Go)\n console.log(\n '[MagicPixel DeviceInfoHelper] react-native-device-info not available, trying Expo modules'\n );\n }\n\n // SECOND: Fall back to Expo modules (for Expo Go where native modules don't work)\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoApp = require('expo-application');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoDevice = require('expo-device');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoConst = require('expo-constants');\n\n // Validate modules are actually loaded (not undefined placeholders from Metro)\n if (\n expoApp &&\n expoDevice &&\n expoConst &&\n typeof expoApp.nativeApplicationVersion !== 'undefined'\n ) {\n this.expoApplication = expoApp;\n this.expoDevice = expoDevice;\n this.expoConstants = expoConst.default || expoConst;\n console.log('[MagicPixel DeviceInfoHelper] Using Expo modules');\n }\n } catch (error) {\n // Expo modules not available\n console.log(\n '[MagicPixel DeviceInfoHelper] Expo modules not available, using safe defaults'\n );\n }\n\n this.initialized = true;\n }\n\n /**\n * Get comprehensive app and device information\n * All methods are async-safe and handle errors gracefully\n */\n static async getAppInfo(): Promise<DeviceAppInfo> {\n await this.initialize();\n\n try {\n // Use react-native-device-info if available (preferred)\n if (this.deviceInfo) {\n return await this.getAppInfoFromDeviceInfo();\n }\n\n // Fall back to Expo modules (for Expo Go)\n if (this.expoApplication && this.expoDevice) {\n return await this.getAppInfoFromExpo();\n }\n\n // Return safe fallback values\n return this.getSafeDefaults();\n } catch (error) {\n // Use console.log here as well to be safe\n console.error('[MagicPixel DeviceInfoHelper] Error getting device info:', error);\n return this.getSafeDefaults();\n }\n }\n\n /**\n * Get device info using Expo modules (works in Expo Go)\n */\n private static async getAppInfoFromExpo(): Promise<DeviceAppInfo> {\n const version = this.expoApplication.nativeApplicationVersion || 'unknown';\n const buildNumber = this.expoApplication.nativeBuildVersion || 'unknown';\n const packageName = this.expoApplication.applicationId || 'unknown';\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: packageName,\n\n // Device information\n device_model_name: this.expoDevice.modelName || 'unknown',\n device_manufacturer: this.expoDevice.manufacturer || 'unknown',\n device_id: this.expoConstants.sessionId || 'unknown',\n\n // OS information\n os_name: Platform.OS,\n os_version:\n this.expoDevice.osVersion || Platform.Version?.toString() || 'unknown',\n\n // Additional useful info\n // DeviceType enum: UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4\n is_tablet: this.expoDevice.deviceType === 2, // DeviceType.TABLET = 2\n is_emulator: !this.expoDevice.isDevice,\n };\n }\n\n /**\n * Get device info using react-native-device-info (for bare RN)\n */\n private static async getAppInfoFromDeviceInfo(): Promise<DeviceAppInfo> {\n const [version, buildNumber, uniqueId, bundleId] = await Promise.all([\n this.deviceInfo.getVersion(),\n this.deviceInfo.getBuildNumber(),\n this.deviceInfo.getUniqueId(),\n this.deviceInfo.getBundleId(),\n ]);\n\n return {\n // App information\n app_version: version,\n build_number: buildNumber,\n package_name: bundleId,\n\n // Device information\n device_model_name: this.deviceInfo.getModel(),\n device_manufacturer: this.deviceInfo.getManufacturerSync(),\n device_id: uniqueId,\n\n // OS information\n os_name: Platform.OS,\n os_version: this.deviceInfo.getSystemVersion(),\n\n // Additional useful info\n is_tablet: this.deviceInfo.isTablet(),\n is_emulator: await this.deviceInfo.isEmulator(),\n };\n }\n\n /**\n * Safe default values when no device info library is available\n */\n private static getSafeDefaults(): DeviceAppInfo {\n return {\n app_version: 'unknown',\n build_number: 'unknown',\n package_name: 'unknown',\n device_model_name: 'unknown',\n device_manufacturer: 'unknown',\n device_id: 'unknown',\n os_name: Platform.OS,\n os_version: Platform.Version?.toString() || 'unknown',\n is_tablet: false,\n is_emulator: false,\n };\n }\n\n /**\n * Get app version in format: \"1.0.0 (123)\"\n * Combines version and build number for better tracking\n */\n static async getFormattedAppVersion(): Promise<string> {\n try {\n const info = await this.getAppInfo();\n return `${info.app_version} (${info.build_number})`;\n } catch (error) {\n Logger.logError('Error getting formatted app version:', error);\n return 'unknown';\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=sdk.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["sdk.d.ts"],"sourcesContent":["declare module '@magicpixel/rn-mp-client-sdk' {\n interface InitConfig {\n orgId: string;\n env: 'staging' | 'production';\n projectId: string;\n baseUrl: string;\n logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none';\n eventDeduplicationWindowMs?: number;\n onInitFailure?: (error: Error) => void;\n }\n\n interface UserInfo {\n pid?: string;\n email?: string;\n phone?: string;\n country?: string;\n city?: string;\n state?: string;\n fName?: string;\n lName?: string;\n zip?: string;\n }\n\n interface PageLoadData {\n page_name: string;\n [key: string]: any;\n }\n\n class MagicPixelImpl {\n init(config: InitConfig): void;\n shutdown(): void;\n recordEvent(eventName: string, payload?: Record<string, any>): void;\n recordPageLoad(data: PageLoadData): void;\n setUserInfo(userInfo: UserInfo): void;\n setCustomerInfo(customerInfo: Record<string, any>): void;\n setDeviceInfo(customFields?: Record<string, any>): void;\n setDeepLinkUrl(url: string): void;\n setFirebaseAppInstanceId(id: string): void;\n getDebugId(): Promise<string | null>;\n setDataLayer(data: Record<string, any>): void;\n persistData(key: string, value: any): void;\n clearPersistedData(keys: string[]): void;\n getDataLayer(): Record<string, any>;\n getEventState(): Record<string, any>;\n hasEventHappened(eventName: string): boolean;\n registerEventProcessor(\n eventType: string,\n callback: (event: any) => void\n ): void;\n }\n\n export const MagicPixel: MagicPixelImpl;\n export const MagicPixelEventBus: any;\n}\n"],"mappings":"","ignoreList":[]}
@@ -13,8 +13,8 @@ interface DeviceAppInfo {
13
13
  /**
14
14
  * Helper class to automatically detect device and app information
15
15
  * Supports both Expo and bare React Native:
16
- * 1. Tries Expo modules first (works in Expo Go)
17
- * 2. Falls back to react-native-device-info (for bare RN)
16
+ * 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)
17
+ * 2. Falls back to Expo modules (for Expo Go where native modules don't work)
18
18
  * 3. Returns safe defaults if neither is available
19
19
  */
20
20
  export declare class DeviceInfoHelper {
@@ -24,8 +24,8 @@ export declare class DeviceInfoHelper {
24
24
  private static deviceInfo;
25
25
  private static initialized;
26
26
  /**
27
- * Try to load Expo modules and react-native-device-info
28
- * This uses dynamic imports to avoid errors when modules aren't available
27
+ * Try to load react-native-device-info first, then Expo modules
28
+ * Uses console.log during init to avoid Logger dependency issues if module loading fails
29
29
  */
30
30
  private static initialize;
31
31
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magicpixel/rn-mp-client-sdk",
3
- "version": "1.13.21",
3
+ "version": "1.13.23",
4
4
  "description": "React Native SDK for MagicPixel analytics and tag management",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -10,6 +10,7 @@
10
10
  "files": [
11
11
  "src",
12
12
  "lib",
13
+ "scripts",
13
14
  "!lib/typescript/example",
14
15
  "!**/__tests__",
15
16
  "!**/__fixtures__",
@@ -20,6 +21,7 @@
20
21
  "typescript": "tsc --noEmit",
21
22
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
22
23
  "prepare": "bob build",
24
+ "postinstall": "node scripts/postinstall.js",
23
25
  "release": "release-it",
24
26
  "example": "yarn --cwd example",
25
27
  "bootstrap": "yarn example && yarn && yarn example pods",
@@ -91,7 +93,13 @@
91
93
  },
92
94
  "peerDependencies": {
93
95
  "react": "*",
94
- "react-native": "*"
96
+ "react-native": "*",
97
+ "react-native-get-random-values": ">=1.8.0"
98
+ },
99
+ "peerDependenciesMeta": {
100
+ "react-native-get-random-values": {
101
+ "optional": true
102
+ }
95
103
  },
96
104
  "commitlint": {
97
105
  "extends": [
@@ -0,0 +1,29 @@
1
+ const os = require('os');
2
+ const path = require('path');
3
+ const child_process = require('child_process');
4
+
5
+ const root = path.resolve(__dirname, '..');
6
+ const args = process.argv.slice(2);
7
+ const options = {
8
+ cwd: process.cwd(),
9
+ env: process.env,
10
+ stdio: 'inherit',
11
+ encoding: 'utf-8',
12
+ };
13
+
14
+ if (os.type() === 'Windows_NT') {
15
+ options.shell = true;
16
+ }
17
+
18
+ let result;
19
+
20
+ if (process.cwd() !== root || args.length) {
21
+ // We're not in the root of the project, or additional arguments were passed
22
+ // In this case, forward the command to `yarn`
23
+ result = child_process.spawnSync('yarn', args, options);
24
+ } else {
25
+ // If `yarn` is run without arguments, perform bootstrap
26
+ result = child_process.spawnSync('yarn', ['bootstrap'], options);
27
+ }
28
+
29
+ process.exitCode = result.status;
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * MagicPixel SDK Postinstall Script
5
+ * Detects bare React Native projects and displays setup instructions
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ // ANSI color codes
12
+ const colors = {
13
+ reset: '\x1b[0m',
14
+ bright: '\x1b[1m',
15
+ dim: '\x1b[2m',
16
+ yellow: '\x1b[33m',
17
+ cyan: '\x1b[36m',
18
+ white: '\x1b[37m',
19
+ bgMagenta: '\x1b[45m',
20
+ bgBlue: '\x1b[44m',
21
+ };
22
+
23
+ function getAppRoot() {
24
+ // Navigate up from node_modules/@magicpixel/rn-mp-client-sdk/scripts
25
+ // Structure: <app>/node_modules/@magicpixel/rn-mp-client-sdk/scripts/postinstall.js
26
+ // Or with yalc: <app>/.yalc/@magicpixel/rn-mp-client-sdk/scripts/postinstall.js
27
+ let current = __dirname;
28
+
29
+ for (let i = 0; i < 10; i++) {
30
+ current = path.dirname(current);
31
+ const packageJsonPath = path.join(current, 'package.json');
32
+
33
+ if (fs.existsSync(packageJsonPath)) {
34
+ try {
35
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
36
+ // Skip our own package.json
37
+ if (pkg.name === '@magicpixel/rn-mp-client-sdk') {
38
+ continue;
39
+ }
40
+ // Found the host app
41
+ return current;
42
+ } catch (e) {
43
+ // Continue searching
44
+ }
45
+ }
46
+ }
47
+ return null;
48
+ }
49
+
50
+ function detectProjectType(appRoot) {
51
+ if (!appRoot) return 'unknown';
52
+
53
+ const hasIosFolder = fs.existsSync(path.join(appRoot, 'ios'));
54
+ const hasAndroidFolder = fs.existsSync(path.join(appRoot, 'android'));
55
+ const hasPodfile = fs.existsSync(path.join(appRoot, 'ios', 'Podfile'));
56
+
57
+ // Check for Expo
58
+ let hasExpo = false;
59
+ try {
60
+ const packageJsonPath = path.join(appRoot, 'package.json');
61
+ if (fs.existsSync(packageJsonPath)) {
62
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
63
+ hasExpo = !!(
64
+ pkg.dependencies?.expo ||
65
+ pkg.devDependencies?.expo ||
66
+ pkg.dependencies?.['expo-modules-core']
67
+ );
68
+ }
69
+ } catch (e) {
70
+ // Ignore errors
71
+ }
72
+
73
+ if (hasExpo && !hasIosFolder && !hasAndroidFolder) {
74
+ return 'expo-managed';
75
+ }
76
+ if (hasExpo && (hasIosFolder || hasAndroidFolder)) {
77
+ return 'expo-bare';
78
+ }
79
+ if (!hasExpo && (hasIosFolder || hasAndroidFolder)) {
80
+ return 'bare-rn';
81
+ }
82
+ return 'unknown';
83
+ }
84
+
85
+ function printBareRNMessage() {
86
+ const c = colors;
87
+ // Use stderr for better visibility (npm sometimes hides stdout from postinstall)
88
+ const log = (msg) => process.stderr.write(msg + '\n');
89
+
90
+ log('');
91
+ log(`${c.bgMagenta}${c.white}${c.bright} ${c.reset}`);
92
+ log(`${c.bgMagenta}${c.white}${c.bright} ╔═══════════════════════════════════════════════════════════════╗ ${c.reset}`);
93
+ log(`${c.bgMagenta}${c.white}${c.bright} ║ ║ ${c.reset}`);
94
+ log(`${c.bgMagenta}${c.white}${c.bright} ║ 🔮 MAGICPIXEL SDK - BARE REACT NATIVE SETUP REQUIRED 🔮 ║ ${c.reset}`);
95
+ log(`${c.bgMagenta}${c.white}${c.bright} ║ ║ ${c.reset}`);
96
+ log(`${c.bgMagenta}${c.white}${c.bright} ╚═══════════════════════════════════════════════════════════════╝ ${c.reset}`);
97
+ log(`${c.bgMagenta}${c.white}${c.bright} ${c.reset}`);
98
+ log('');
99
+ log(`${c.cyan}${c.bright} Complete these steps to finish SDK installation:${c.reset}`);
100
+ log('');
101
+ log(`${c.yellow}${c.bright} STEP 1:${c.reset} Link native modules (iOS)`);
102
+ log(`${c.dim} ─────────────────────────────────────${c.reset}`);
103
+ log(` ${c.white}cd ios && pod install && cd ..${c.reset}`);
104
+ log('');
105
+ log(`${c.yellow}${c.bright} STEP 2:${c.reset} Add polyfill to index.js ${c.dim}(MUST be first import!)${c.reset}`);
106
+ log(`${c.dim} ─────────────────────────────────────${c.reset}`);
107
+ log(` ${c.white}import 'react-native-get-random-values';${c.reset}`);
108
+ log('');
109
+ log(`${c.yellow}${c.bright} STEP 3:${c.reset} Rebuild your app ${c.dim}(required after pod install)${c.reset}`);
110
+ log(`${c.dim} ─────────────────────────────────────${c.reset}`);
111
+ log(` ${c.white}• Kill the app in simulator/device${c.reset}`);
112
+ log(` ${c.white}• Stop Metro (Ctrl+C)${c.reset}`);
113
+ log(` ${c.white}• Run: npx react-native run-ios${c.reset}`);
114
+ log('');
115
+ log(`${c.dim} ⚠️ Without these steps, you'll see:${c.reset}`);
116
+ log(`${c.dim} TurboModuleRegistry.getEnforcing(...): 'RNGetRandomValues' not found${c.reset}`);
117
+ log('');
118
+ log(`${c.dim} 📖 Full docs: https://github.com/digital-madtech/mp-rn-client-sdk#readme${c.reset}`);
119
+ log('');
120
+ }
121
+
122
+ function main() {
123
+ try {
124
+ const appRoot = getAppRoot();
125
+ const projectType = detectProjectType(appRoot);
126
+
127
+ if (projectType === 'bare-rn' || projectType === 'expo-bare') {
128
+ printBareRNMessage();
129
+ }
130
+ // For expo-managed, no message needed - it handles native modules automatically
131
+ } catch (error) {
132
+ // Silently fail - don't break npm install
133
+ }
134
+ }
135
+
136
+ main();
@@ -17,8 +17,8 @@ interface DeviceAppInfo {
17
17
  /**
18
18
  * Helper class to automatically detect device and app information
19
19
  * Supports both Expo and bare React Native:
20
- * 1. Tries Expo modules first (works in Expo Go)
21
- * 2. Falls back to react-native-device-info (for bare RN)
20
+ * 1. Tries react-native-device-info first (works in bare RN and Expo custom builds)
21
+ * 2. Falls back to Expo modules (for Expo Go where native modules don't work)
22
22
  * 3. Returns safe defaults if neither is available
23
23
  */
24
24
  export class DeviceInfoHelper {
@@ -29,39 +29,63 @@ export class DeviceInfoHelper {
29
29
  private static initialized = false;
30
30
 
31
31
  /**
32
- * Try to load Expo modules and react-native-device-info
33
- * This uses dynamic imports to avoid errors when modules aren't available
32
+ * Try to load react-native-device-info first, then Expo modules
33
+ * Uses console.log during init to avoid Logger dependency issues if module loading fails
34
34
  */
35
35
  private static async initialize(): Promise<void> {
36
36
  if (this.initialized) return;
37
37
 
38
- // Try to load Expo modules first (works in Expo Go)
38
+ // FIRST: Try react-native-device-info (preferred - works in bare RN and Expo custom builds)
39
+ // This is a direct dependency of the SDK, so it should always be available except in Expo Go
39
40
  try {
40
41
  // eslint-disable-next-line @typescript-eslint/no-var-requires
41
- this.expoApplication = require('expo-application');
42
- // eslint-disable-next-line @typescript-eslint/no-var-requires
43
- this.expoDevice = require('expo-device');
44
- // eslint-disable-next-line @typescript-eslint/no-var-requires
45
- this.expoConstants = require('expo-constants').default;
46
- Logger.logDbg('Using Expo modules for device info');
42
+ const rnDeviceInfo = require('react-native-device-info');
43
+ // Validate the module is actually loaded and functional
44
+ if (
45
+ rnDeviceInfo &&
46
+ typeof (rnDeviceInfo.default || rnDeviceInfo).getVersion === 'function'
47
+ ) {
48
+ this.deviceInfo = rnDeviceInfo.default || rnDeviceInfo;
49
+ this.initialized = true;
50
+ // Use console.log to avoid any Logger issues during early init
51
+ console.log(
52
+ '[MagicPixel DeviceInfoHelper] Using react-native-device-info'
53
+ );
54
+ return;
55
+ }
47
56
  } catch (error) {
48
- Logger.logDbg(
49
- 'Expo modules not available, will try react-native-device-info'
57
+ // react-native-device-info not available (likely Expo Go)
58
+ console.log(
59
+ '[MagicPixel DeviceInfoHelper] react-native-device-info not available, trying Expo modules'
50
60
  );
51
61
  }
52
62
 
53
- // Fall back to react-native-device-info (for bare RN)
54
- if (!this.expoApplication) {
55
- try {
56
- // eslint-disable-next-line @typescript-eslint/no-var-requires
57
- this.deviceInfo = require('react-native-device-info').default;
58
- Logger.logDbg('Using react-native-device-info for device info');
59
- } catch (error) {
60
- Logger.logError(
61
- 'Neither Expo modules nor react-native-device-info available:',
62
- error
63
- );
63
+ // SECOND: Fall back to Expo modules (for Expo Go where native modules don't work)
64
+ try {
65
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
66
+ const expoApp = require('expo-application');
67
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
68
+ const expoDevice = require('expo-device');
69
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
70
+ const expoConst = require('expo-constants');
71
+
72
+ // Validate modules are actually loaded (not undefined placeholders from Metro)
73
+ if (
74
+ expoApp &&
75
+ expoDevice &&
76
+ expoConst &&
77
+ typeof expoApp.nativeApplicationVersion !== 'undefined'
78
+ ) {
79
+ this.expoApplication = expoApp;
80
+ this.expoDevice = expoDevice;
81
+ this.expoConstants = expoConst.default || expoConst;
82
+ console.log('[MagicPixel DeviceInfoHelper] Using Expo modules');
64
83
  }
84
+ } catch (error) {
85
+ // Expo modules not available
86
+ console.log(
87
+ '[MagicPixel DeviceInfoHelper] Expo modules not available, using safe defaults'
88
+ );
65
89
  }
66
90
 
67
91
  this.initialized = true;
@@ -75,20 +99,21 @@ export class DeviceInfoHelper {
75
99
  await this.initialize();
76
100
 
77
101
  try {
78
- // Try Expo modules first
79
- if (this.expoApplication && this.expoDevice) {
80
- return await this.getAppInfoFromExpo();
81
- }
82
-
83
- // Fall back to react-native-device-info
102
+ // Use react-native-device-info if available (preferred)
84
103
  if (this.deviceInfo) {
85
104
  return await this.getAppInfoFromDeviceInfo();
86
105
  }
87
106
 
107
+ // Fall back to Expo modules (for Expo Go)
108
+ if (this.expoApplication && this.expoDevice) {
109
+ return await this.getAppInfoFromExpo();
110
+ }
111
+
88
112
  // Return safe fallback values
89
113
  return this.getSafeDefaults();
90
114
  } catch (error) {
91
- Logger.logError('Error getting device info:', error);
115
+ // Use console.log here as well to be safe
116
+ console.error('[MagicPixel DeviceInfoHelper] Error getting device info:', error);
92
117
  return this.getSafeDefaults();
93
118
  }
94
119
  }
@@ -0,0 +1,54 @@
1
+ declare module '@magicpixel/rn-mp-client-sdk' {
2
+ interface InitConfig {
3
+ orgId: string;
4
+ env: 'staging' | 'production';
5
+ projectId: string;
6
+ baseUrl: string;
7
+ logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none';
8
+ eventDeduplicationWindowMs?: number;
9
+ onInitFailure?: (error: Error) => void;
10
+ }
11
+
12
+ interface UserInfo {
13
+ pid?: string;
14
+ email?: string;
15
+ phone?: string;
16
+ country?: string;
17
+ city?: string;
18
+ state?: string;
19
+ fName?: string;
20
+ lName?: string;
21
+ zip?: string;
22
+ }
23
+
24
+ interface PageLoadData {
25
+ page_name: string;
26
+ [key: string]: any;
27
+ }
28
+
29
+ class MagicPixelImpl {
30
+ init(config: InitConfig): void;
31
+ shutdown(): void;
32
+ recordEvent(eventName: string, payload?: Record<string, any>): void;
33
+ recordPageLoad(data: PageLoadData): void;
34
+ setUserInfo(userInfo: UserInfo): void;
35
+ setCustomerInfo(customerInfo: Record<string, any>): void;
36
+ setDeviceInfo(customFields?: Record<string, any>): void;
37
+ setDeepLinkUrl(url: string): void;
38
+ setFirebaseAppInstanceId(id: string): void;
39
+ getDebugId(): Promise<string | null>;
40
+ setDataLayer(data: Record<string, any>): void;
41
+ persistData(key: string, value: any): void;
42
+ clearPersistedData(keys: string[]): void;
43
+ getDataLayer(): Record<string, any>;
44
+ getEventState(): Record<string, any>;
45
+ hasEventHappened(eventName: string): boolean;
46
+ registerEventProcessor(
47
+ eventType: string,
48
+ callback: (event: any) => void
49
+ ): void;
50
+ }
51
+
52
+ export const MagicPixel: MagicPixelImpl;
53
+ export const MagicPixelEventBus: any;
54
+ }