@magicpixel/rn-mp-client-sdk 1.13.22 → 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 +44 -5
- package/package.json +10 -2
- package/scripts/bootstrap.js +29 -0
- package/scripts/postinstall.js +136 -0
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
|
|
17
|
+
### For Bare React Native
|
|
18
18
|
|
|
19
|
-
|
|
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
|
-
|
|
23
|
-
|
|
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
|
-
> **
|
|
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
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magicpixel/rn-mp-client-sdk",
|
|
3
|
-
"version": "1.13.
|
|
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();
|