@bennyblader/ddk-rn 0.2.2 → 0.2.3

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.
@@ -2,48 +2,36 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
- const https = require('https');
6
5
  const { execSync } = require('child_process');
7
6
 
8
7
  const packageRoot = path.join(__dirname, '..');
9
- const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
10
- const version = packageJson.version;
11
8
 
12
- const GITHUB_REPO = 'bennyhodl/ddk-ffi';
13
- const RELEASE_TAG = `v${version}`;
9
+ console.log('šŸ“¦ DDK-RN Post-install: Generating turbo modules and building native libraries...');
14
10
 
15
- console.log(`šŸ“¦ DDK-RN Post-install: Setting up native binaries for v${version}...`);
11
+ // Check if uniffi-bindgen-react-native is available (prefer npx)
12
+ function hasUniffiBingen() {
13
+ try {
14
+ execSync('npx uniffi-bindgen-react-native --help', { stdio: 'ignore' });
15
+ return true;
16
+ } catch (error) {
17
+ try {
18
+ execSync('uniffi-bindgen-react-native --help', { stdio: 'ignore' });
19
+ return true;
20
+ } catch (error2) {
21
+ return false;
22
+ }
23
+ }
24
+ }
16
25
 
17
- // Define all required files for verification
18
- const requiredFiles = {
19
- 'TypeScript bindings': [
20
- 'src/ddk_ffi.ts',
21
- 'src/ddk_ffi-ffi.ts',
22
- 'src/NativeDdkRn.ts',
23
- 'src/index.tsx'
24
- ],
25
- 'C++ bindings': [
26
- 'cpp/ddk_ffi.hpp',
27
- 'cpp/ddk_ffi.cpp',
28
- 'cpp/bennyblader-ddk-rn.h',
29
- 'cpp/bennyblader-ddk-rn.cpp'
30
- ],
31
- 'Android libraries': [
32
- 'android/src/main/arm64-v8a/libddk_ffi.a',
33
- 'android/src/main/armeabi-v7a/libddk_ffi.a',
34
- 'android/src/main/x86/libddk_ffi.a',
35
- 'android/src/main/x86_64/libddk_ffi.a'
36
- ],
37
- 'iOS framework': [
38
- 'ios/DdkRn.xcframework/Info.plist',
39
- 'ios/DdkRn.xcframework/ios-arm64/libddk_ffi.a',
40
- 'ios/DdkRn.xcframework/ios-arm64-simulator/libddk_ffi.a'
41
- ],
42
- 'JavaScript modules': [
43
- 'lib/commonjs/index.js',
44
- 'lib/module/index.js'
45
- ]
46
- };
26
+ // Get the uniffi command (prefer npx)
27
+ function getUniffiCommand() {
28
+ try {
29
+ execSync('npx uniffi-bindgen-react-native --help', { stdio: 'ignore' });
30
+ return 'npx uniffi-bindgen-react-native';
31
+ } catch (error) {
32
+ return 'uniffi-bindgen-react-native';
33
+ }
34
+ }
47
35
 
48
36
  // Create directories if they don't exist
49
37
  function ensureDir(dir) {
@@ -52,178 +40,243 @@ function ensureDir(dir) {
52
40
  }
53
41
  }
54
42
 
55
- function downloadFile(url, dest) {
56
- return new Promise((resolve, reject) => {
57
- console.log(`ā¬‡ļø Downloading from ${url}...`);
58
-
59
- const file = fs.createWriteStream(dest);
60
-
61
- https.get(url, (response) => {
62
- if (response.statusCode === 302 || response.statusCode === 301) {
63
- // Follow redirect
64
- return downloadFile(response.headers.location, dest).then(resolve).catch(reject);
65
- }
66
-
67
- if (response.statusCode !== 200) {
68
- reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`));
69
- return;
70
- }
71
-
72
- response.pipe(file);
73
-
74
- file.on('finish', () => {
75
- file.close();
76
- console.log(`āœ… Downloaded ${path.basename(dest)}`);
77
- resolve();
78
- });
79
- }).on('error', (err) => {
80
- fs.unlink(dest, () => {}); // Delete partial file
81
- reject(err);
82
- });
83
- });
84
- }
85
-
86
- function extractTarGz(tarPath, extractDir) {
43
+ // Generate turbo module specifications from existing JSI bindings
44
+ function generateTurboModule() {
45
+ console.log('\n⚔ Generating turbo module from existing bindings...');
46
+
47
+ const configFile = path.join(packageRoot, 'ubrn.config.yaml');
48
+ const uniffiCmd = getUniffiCommand();
49
+
87
50
  try {
88
- console.log(`šŸ“‚ Extracting ${path.basename(tarPath)}...`);
89
- execSync(`tar -xzf "${tarPath}" -C "${extractDir}"`, { stdio: 'inherit' });
90
- console.log(`āœ… Extracted to ${extractDir}`);
51
+ const cmd = `${uniffiCmd} generate jsi turbo-module ddk_ffi --config "${configFile}" --native-bindings`;
52
+ console.log(`Running: ${cmd}`);
53
+ execSync(cmd, {
54
+ stdio: 'inherit',
55
+ cwd: packageRoot
56
+ });
57
+ console.log('āœ… Turbo module generated');
91
58
  } catch (error) {
92
- throw new Error(`Failed to extract ${tarPath}: ${error.message}`);
59
+ throw new Error(`Failed to generate turbo module: ${error.message}`);
93
60
  }
94
61
  }
95
62
 
96
- function verifyAllFiles() {
97
- console.log('\nšŸ” Verifying all required files...');
98
-
99
- let allFilesPresent = true;
63
+ // Build iOS libraries and create XCFramework
64
+ function buildIOS() {
100
65
  const platform = process.platform;
101
66
 
102
- for (const [category, files] of Object.entries(requiredFiles)) {
103
- // Skip iOS files on non-macOS platforms
104
- if (category === 'iOS framework' && platform !== 'darwin') {
105
- console.log(`\nāš ļø Skipping ${category} verification (not on macOS)`);
106
- continue;
107
- }
108
-
109
- console.log(`\nšŸ“‹ Checking ${category}...`);
110
-
111
- for (const file of files) {
112
- const filePath = path.join(packageRoot, file);
113
- if (fs.existsSync(filePath)) {
114
- console.log(` āœ… ${file}`);
115
- } else {
116
- console.error(` āŒ Missing: ${file}`);
117
- allFilesPresent = false;
118
- }
119
- }
67
+ if (platform !== 'darwin') {
68
+ console.log('\nāš ļø Skipping iOS build (not on macOS)');
69
+ return;
120
70
  }
121
71
 
122
- return allFilesPresent;
72
+ console.log('\nšŸŽ Building iOS libraries...');
73
+ const uniffiCmd = getUniffiCommand();
74
+
75
+ try {
76
+ const cmd = `${uniffiCmd} build ios --and-generate`;
77
+ console.log(`Running: ${cmd}`);
78
+ execSync(cmd, {
79
+ stdio: 'inherit',
80
+ cwd: packageRoot
81
+ });
82
+ console.log('āœ… iOS libraries built');
83
+ } catch (error) {
84
+ throw new Error(`Failed to build iOS libraries: ${error.message}`);
85
+ }
123
86
  }
124
87
 
125
- async function downloadAndExtractBinaries() {
126
- const platform = process.platform;
88
+ // Build Android libraries
89
+ function buildAndroid() {
90
+ console.log('\nšŸ“± Building Android libraries...');
91
+
92
+ // Check if Android NDK is available
93
+ if (!process.env.ANDROID_NDK_ROOT && !process.env.NDK_HOME) {
94
+ console.log('āš ļø Android NDK not found. Skipping Android build.');
95
+ console.log(' Set ANDROID_NDK_ROOT or NDK_HOME to build Android libraries.');
96
+ return;
97
+ }
98
+
99
+ const uniffiCmd = getUniffiCommand();
127
100
 
128
101
  try {
129
- // Download Android native libraries
130
- const androidLibsDir = path.join(packageRoot, 'android', 'src', 'main');
131
- ensureDir(androidLibsDir);
132
-
133
- const androidArchiveUrl = `https://github.com/${GITHUB_REPO}/releases/download/${RELEASE_TAG}/android-jni-libs.tar.gz`;
134
- const androidTarPath = path.join(packageRoot, 'android-jni-libs.tar.gz');
135
-
136
- console.log('\nšŸ“± Setting up Android native libraries...');
137
- await downloadFile(androidArchiveUrl, androidTarPath);
138
- extractTarGz(androidTarPath, androidLibsDir);
139
- fs.unlinkSync(androidTarPath); // Clean up tar file
140
-
141
- // Download iOS XCFramework (only on macOS)
142
- if (platform === 'darwin') {
143
- const iosFrameworksDir = path.join(packageRoot, 'ios');
144
- ensureDir(iosFrameworksDir);
145
-
146
- const iosArchiveUrl = `https://github.com/${GITHUB_REPO}/releases/download/${RELEASE_TAG}/ios-xcframeworks.tar.gz`;
147
- const iosTarPath = path.join(packageRoot, 'ios-xcframeworks.tar.gz');
148
-
149
- console.log('\nšŸŽ Setting up iOS framework...');
150
- await downloadFile(iosArchiveUrl, iosTarPath);
151
- extractTarGz(iosTarPath, iosFrameworksDir);
152
- fs.unlinkSync(iosTarPath); // Clean up tar file
153
- } else {
154
- console.log('\nāš ļø Skipping iOS framework (not on macOS)');
155
- }
156
-
102
+ const cmd = `${uniffiCmd} build android --and-generate`;
103
+ console.log(`Running: ${cmd}`);
104
+ execSync(cmd, {
105
+ stdio: 'inherit',
106
+ cwd: packageRoot
107
+ });
108
+ console.log('āœ… Android libraries built');
157
109
  } catch (error) {
158
- console.error('\nāŒ Failed to download native binaries:', error.message);
159
- console.error('');
160
- console.error('šŸ“‹ Manual installation instructions:');
161
- console.error(` 1. Download binaries from: https://github.com/${GITHUB_REPO}/releases/tag/${RELEASE_TAG}`);
162
- console.error(' 2. Extract android-jni-libs.tar.gz to android/src/main/');
163
- console.error(' 3. Extract ios-xcframeworks.tar.gz to ios/ (macOS only)');
164
- console.error('');
165
- console.error('Or report this issue at: https://github.com/bennyhodl/ddk-ffi/issues');
166
-
167
- // Don't fail the installation completely
168
- process.exit(0);
110
+ console.warn(`āš ļø Android build failed: ${error.message}`);
111
+ console.warn(' This may be due to missing Android NDK or Rust toolchains.');
169
112
  }
170
113
  }
171
114
 
172
- async function main() {
173
- const platform = process.platform;
174
-
175
- // Skip in CI unless explicitly requested
176
- if (process.env.CI && !process.env.DOWNLOAD_BINARIES) {
177
- console.log('āš ļø Skipping binary download in CI environment.');
178
- console.log(' Set DOWNLOAD_BINARIES=1 to force download in CI.');
179
- process.exit(0);
115
+ // Fix the C++ include path issue
116
+ function fixCppIncludePath() {
117
+ const cppFile = path.join(packageRoot, 'cpp', 'bennyblader-ddk-rn.cpp');
118
+ if (fs.existsSync(cppFile)) {
119
+ let content = fs.readFileSync(cppFile, 'utf8');
120
+ if (content.includes('#include "/ddk_ffi.hpp"')) {
121
+ content = content.replace('#include "/ddk_ffi.hpp"', '#include "ddk_ffi.hpp"');
122
+ fs.writeFileSync(cppFile, content);
123
+ console.log('šŸ”§ Fixed include path in C++ bindings');
124
+ }
180
125
  }
126
+ }
127
+
128
+ // Verify all required files are present
129
+ function verifyAllFiles() {
130
+ console.log('\nšŸ” Verifying installation...');
181
131
 
182
- // Check if binaries already exist
183
- const androidLibExists = fs.existsSync(path.join(packageRoot, 'android', 'src', 'main', 'arm64-v8a', 'libddk_ffi.a'));
184
- const iosFrameworkExists = fs.existsSync(path.join(packageRoot, 'ios', 'DdkRn.xcframework'));
132
+ const sourceFiles = [
133
+ 'src/ddk_ffi.ts',
134
+ 'src/ddk_ffi-ffi.ts',
135
+ 'cpp/ddk_ffi.hpp',
136
+ 'cpp/ddk_ffi.cpp'
137
+ ];
185
138
 
186
- let needsDownload = false;
139
+ const generatedFiles = [
140
+ 'src/NativeDdkRn.ts',
141
+ 'src/index.tsx',
142
+ 'cpp/bennyblader-ddk-rn.cpp',
143
+ 'cpp/bennyblader-ddk-rn.h'
144
+ ];
145
+
146
+ const platform = process.platform;
147
+ let allFilesPresent = true;
187
148
 
188
- if (!androidLibExists) {
189
- console.log('šŸ“± Android libraries not found, will download...');
190
- needsDownload = true;
149
+ // Check source files (should be included in NPM package)
150
+ console.log('šŸ“‹ Checking source files...');
151
+ for (const file of sourceFiles) {
152
+ const filePath = path.join(packageRoot, file);
153
+ if (fs.existsSync(filePath)) {
154
+ console.log(` āœ… ${file}`);
155
+ } else {
156
+ console.error(` āŒ Missing: ${file}`);
157
+ allFilesPresent = false;
158
+ }
191
159
  }
192
160
 
193
- if (platform === 'darwin' && !iosFrameworkExists) {
194
- console.log('šŸŽ iOS framework not found, will download...');
195
- needsDownload = true;
161
+ // Check generated files (created by postinstall)
162
+ console.log('šŸ“‹ Checking generated files...');
163
+ for (const file of generatedFiles) {
164
+ const filePath = path.join(packageRoot, file);
165
+ if (fs.existsSync(filePath)) {
166
+ console.log(` āœ… ${file}`);
167
+ } else {
168
+ console.error(` āŒ Missing: ${file}`);
169
+ allFilesPresent = false;
170
+ }
196
171
  }
197
172
 
198
- if (needsDownload) {
199
- await downloadAndExtractBinaries();
173
+ // Check platform-specific files
174
+ if (platform === 'darwin') {
175
+ console.log('šŸ“‹ Checking iOS framework...');
176
+ const iosFramework = path.join(packageRoot, 'ios', 'DdkRn.xcframework', 'Info.plist');
177
+ if (fs.existsSync(iosFramework)) {
178
+ console.log(` āœ… ios/DdkRn.xcframework`);
179
+ } else {
180
+ console.error(` āŒ Missing: ios/DdkRn.xcframework`);
181
+ allFilesPresent = false;
182
+ }
200
183
  } else {
201
- console.log('āœ… Native binaries already present.');
184
+ console.log('šŸ“‹ Skipping iOS framework check (not on macOS)');
202
185
  }
203
186
 
204
- // Fix the C++ include path issue if needed
205
- const cppFile = path.join(packageRoot, 'cpp', 'bennyblader-ddk-rn.cpp');
206
- if (fs.existsSync(cppFile)) {
207
- let content = fs.readFileSync(cppFile, 'utf8');
208
- if (content.includes('#include "/ddk_ffi.hpp"')) {
209
- content = content.replace('#include "/ddk_ffi.hpp"', '#include "ddk_ffi.hpp"');
210
- fs.writeFileSync(cppFile, content);
211
- console.log('\nšŸ”§ Fixed include path in C++ bindings');
187
+ console.log('šŸ“‹ Checking Android libraries...');
188
+ const androidLibs = [
189
+ 'android/src/main/arm64-v8a/libddk_ffi.a',
190
+ 'android/src/main/armeabi-v7a/libddk_ffi.a',
191
+ 'android/src/main/x86/libddk_ffi.a',
192
+ 'android/src/main/x86_64/libddk_ffi.a'
193
+ ];
194
+
195
+ let androidLibsPresent = 0;
196
+ for (const lib of androidLibs) {
197
+ const libPath = path.join(packageRoot, lib);
198
+ if (fs.existsSync(libPath)) {
199
+ console.log(` āœ… ${lib}`);
200
+ androidLibsPresent++;
201
+ } else {
202
+ console.log(` āš ļø Missing: ${lib}`);
212
203
  }
213
204
  }
214
205
 
215
- // Verify all files are present
216
- const allFilesPresent = verifyAllFiles();
206
+ if (androidLibsPresent === 0) {
207
+ console.log(' āš ļø No Android libraries found (may be due to missing NDK)');
208
+ } else {
209
+ console.log(` āœ… Found ${androidLibsPresent}/${androidLibs.length} Android libraries`);
210
+ }
217
211
 
218
- if (!allFilesPresent) {
219
- console.error('\nāŒ Some required files are missing!');
220
- console.error('The package installation may have failed.');
221
- console.error('Please report this issue at: https://github.com/bennyhodl/ddk-ffi/issues');
212
+ return allFilesPresent;
213
+ }
214
+
215
+ async function main() {
216
+ // Skip in CI unless explicitly requested
217
+ if (process.env.CI && !process.env.GENERATE_BINDINGS) {
218
+ console.log('āš ļø Skipping binding generation in CI environment.');
219
+ console.log(' Set GENERATE_BINDINGS=1 to force generation in CI.');
220
+ process.exit(0);
221
+ }
222
+
223
+ // Check prerequisites
224
+ if (!hasUniffiBingen()) {
225
+ console.error('āŒ uniffi-bindgen-react-native not found!');
226
+ console.error(' Install it with: npm install -g uniffi-bindgen-react-native');
227
+ console.error(' Or add it as a dependency in your project.');
222
228
  process.exit(1);
223
229
  }
224
230
 
225
- console.log('\nāœ… All required files verified!');
226
- console.log('šŸŽ‰ DDK-RN is ready to use!\n');
231
+ // Verify source files are present (should be included in NPM package)
232
+ const sourceFiles = [
233
+ 'src/ddk_ffi.ts',
234
+ 'src/ddk_ffi-ffi.ts',
235
+ 'cpp/ddk_ffi.hpp',
236
+ 'cpp/ddk_ffi.cpp'
237
+ ];
238
+
239
+ console.log('šŸ” Checking source files...');
240
+ for (const file of sourceFiles) {
241
+ const filePath = path.join(packageRoot, file);
242
+ if (!fs.existsSync(filePath)) {
243
+ console.error(`āŒ Missing source file: ${file}`);
244
+ console.error(' This indicates a problem with the NPM package.');
245
+ process.exit(1);
246
+ }
247
+ }
248
+ console.log('āœ… All source files present');
249
+
250
+ try {
251
+ // Generate turbo module and build native libraries from existing JSI bindings
252
+ generateTurboModule();
253
+ fixCppIncludePath();
254
+ buildIOS();
255
+ buildAndroid();
256
+
257
+ // Verify all files are present
258
+ const allFilesPresent = verifyAllFiles();
259
+
260
+ if (!allFilesPresent) {
261
+ console.error('\nāŒ Some required files are missing!');
262
+ console.error('The installation may have failed.');
263
+ process.exit(1);
264
+ }
265
+
266
+ console.log('\nāœ… All files installed successfully!');
267
+ console.log('šŸŽ‰ DDK-RN is ready to use!\n');
268
+
269
+ } catch (error) {
270
+ console.error('\nāŒ Failed to complete installation:', error.message);
271
+ console.error('');
272
+ console.error('šŸ“‹ This may be due to:');
273
+ console.error(' - Missing uniffi-bindgen-react-native (install globally)');
274
+ console.error(' - Missing Android NDK (for Android builds)');
275
+ console.error(' - Missing Xcode/iOS toolchain (for iOS builds on macOS)');
276
+ console.error('');
277
+ console.error('Report issues at: https://github.com/bennyhodl/ddk-ffi/issues');
278
+ process.exit(1);
279
+ }
227
280
  }
228
281
 
229
282
  // Run the main function