@bennyblader/ddk-rn 0.2.3 → 0.2.5

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.
@@ -0,0 +1,3 @@
1
+ fn main() {
2
+ uniffi::uniffi_bindgen_main()
3
+ }
@@ -0,0 +1,18 @@
1
+ # uniffi.toml
2
+ [bindings.typescript]
3
+ logLevel = "verbose"
4
+
5
+ [bindings.cpp]
6
+
7
+ [turbo_module]
8
+ # The name of your Turbo Module as it appears in React Native
9
+ name = "Ddk"
10
+ # The iOS framework name
11
+ ios_framework = "Ddk"
12
+ # The Android package name
13
+ android_package = "dev.bennyblader.ddk"
14
+
15
+ [namespace.ddk_ffi]
16
+ # Configuration specific to your ddk_ffi namespace
17
+ # This tells the generator how to handle this particular namespace
18
+ js_module_name = "Ddk"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bennyblader/ddk-rn",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "dlcdevkit bindings for react-native",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/commonjs/index.js",
@@ -19,11 +19,10 @@
19
19
  }
20
20
  },
21
21
  "files": [
22
- "src/ddk_ffi.ts",
23
- "src/ddk_ffi-ffi.ts",
24
- "cpp/ddk_ffi.hpp",
25
- "cpp/ddk_ffi.cpp",
22
+ "src",
23
+ "cpp",
26
24
  "lib",
25
+ "ddk-ffi",
27
26
  "android/build.gradle",
28
27
  "android/CMakeLists.txt",
29
28
  "android/cpp-adapter.cpp",
@@ -35,10 +34,12 @@
35
34
  "ios/DdkRn.h",
36
35
  "ios/DdkRn.mm",
37
36
  "scripts/postinstall.js",
37
+ "scripts/prepare-rust-src.js",
38
38
  "ubrn.config.yaml",
39
39
  "*.podspec",
40
40
  "react-native.config.js",
41
41
  "README.md",
42
+ "!ddk-ffi/target",
42
43
  "!**/*.a",
43
44
  "!**/*.so",
44
45
  "!**/*.dylib",
@@ -5,8 +5,9 @@ const path = require('path');
5
5
  const { execSync } = require('child_process');
6
6
 
7
7
  const packageRoot = path.join(__dirname, '..');
8
+ const ddkFfiRoot = path.join(packageRoot, 'ddk-ffi');
8
9
 
9
- console.log('šŸ“¦ DDK-RN Post-install: Generating turbo modules and building native libraries...');
10
+ console.log('šŸ“¦ DDK-RN Post-install: Building native libraries...');
10
11
 
11
12
  // Check if uniffi-bindgen-react-native is available (prefer npx)
12
13
  function hasUniffiBingen() {
@@ -40,26 +41,6 @@ function ensureDir(dir) {
40
41
  }
41
42
  }
42
43
 
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
-
50
- try {
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');
58
- } catch (error) {
59
- throw new Error(`Failed to generate turbo module: ${error.message}`);
60
- }
61
- }
62
-
63
44
  // Build iOS libraries and create XCFramework
64
45
  function buildIOS() {
65
46
  const platform = process.platform;
@@ -72,6 +53,9 @@ function buildIOS() {
72
53
  console.log('\nšŸŽ Building iOS libraries...');
73
54
  const uniffiCmd = getUniffiCommand();
74
55
 
56
+ // Update ubrn.config.yaml to point to the included Rust source
57
+ updateConfigFile();
58
+
75
59
  try {
76
60
  const cmd = `${uniffiCmd} build ios --and-generate`;
77
61
  console.log(`Running: ${cmd}`);
@@ -98,6 +82,9 @@ function buildAndroid() {
98
82
 
99
83
  const uniffiCmd = getUniffiCommand();
100
84
 
85
+ // Update ubrn.config.yaml to point to the included Rust source
86
+ updateConfigFile();
87
+
101
88
  try {
102
89
  const cmd = `${uniffiCmd} build android --and-generate`;
103
90
  console.log(`Running: ${cmd}`);
@@ -112,7 +99,26 @@ function buildAndroid() {
112
99
  }
113
100
  }
114
101
 
115
- // Fix the C++ include path issue
102
+ // Update the ubrn.config.yaml to use the local Rust source
103
+ function updateConfigFile() {
104
+ const configPath = path.join(packageRoot, 'ubrn.config.yaml');
105
+
106
+ if (fs.existsSync(configPath)) {
107
+ let config = fs.readFileSync(configPath, 'utf8');
108
+
109
+ // Update the Rust directory to point to the included ddk-ffi
110
+ if (!config.includes('directory: ddk-ffi')) {
111
+ config = config.replace(
112
+ /rust:\s*\n\s*directory:\s*[^\n]+/,
113
+ 'rust:\n directory: ddk-ffi'
114
+ );
115
+ fs.writeFileSync(configPath, config);
116
+ console.log('šŸ“ Updated config to use included Rust source');
117
+ }
118
+ }
119
+ }
120
+
121
+ // Fix the C++ include path issue if needed
116
122
  function fixCppIncludePath() {
117
123
  const cppFile = path.join(packageRoot, 'cpp', 'bennyblader-ddk-rn.cpp');
118
124
  if (fs.existsSync(cppFile)) {
@@ -129,38 +135,29 @@ function fixCppIncludePath() {
129
135
  function verifyAllFiles() {
130
136
  console.log('\nšŸ” Verifying installation...');
131
137
 
132
- const sourceFiles = [
138
+ const requiredFiles = [
139
+ // Core JSI bindings (shipped with package)
133
140
  'src/ddk_ffi.ts',
134
141
  'src/ddk_ffi-ffi.ts',
135
142
  'cpp/ddk_ffi.hpp',
136
- 'cpp/ddk_ffi.cpp'
137
- ];
138
-
139
- const generatedFiles = [
143
+ 'cpp/ddk_ffi.cpp',
144
+ // Generated turbo module files (shipped with package)
140
145
  'src/NativeDdkRn.ts',
141
146
  'src/index.tsx',
142
147
  'cpp/bennyblader-ddk-rn.cpp',
143
- 'cpp/bennyblader-ddk-rn.h'
148
+ 'cpp/bennyblader-ddk-rn.h',
149
+ // Rust source (shipped with package)
150
+ 'ddk-ffi/Cargo.toml',
151
+ 'ddk-ffi/src/lib.rs',
152
+ 'ddk-ffi/src/ddk_ffi.udl'
144
153
  ];
145
154
 
146
155
  const platform = process.platform;
147
156
  let allFilesPresent = true;
148
157
 
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
- }
159
- }
160
-
161
- // Check generated files (created by postinstall)
162
- console.log('šŸ“‹ Checking generated files...');
163
- for (const file of generatedFiles) {
158
+ // Check required files
159
+ console.log('šŸ“‹ Checking required files...');
160
+ for (const file of requiredFiles) {
164
161
  const filePath = path.join(packageRoot, file);
165
162
  if (fs.existsSync(filePath)) {
166
163
  console.log(` āœ… ${file}`);
@@ -170,18 +167,15 @@ function verifyAllFiles() {
170
167
  }
171
168
  }
172
169
 
173
- // Check platform-specific files
170
+ // Check platform-specific files (generated during postinstall)
174
171
  if (platform === 'darwin') {
175
172
  console.log('šŸ“‹ Checking iOS framework...');
176
173
  const iosFramework = path.join(packageRoot, 'ios', 'DdkRn.xcframework', 'Info.plist');
177
174
  if (fs.existsSync(iosFramework)) {
178
175
  console.log(` āœ… ios/DdkRn.xcframework`);
179
176
  } else {
180
- console.error(` āŒ Missing: ios/DdkRn.xcframework`);
181
- allFilesPresent = false;
177
+ console.log(` āš ļø iOS framework not built yet (will be built now)`);
182
178
  }
183
- } else {
184
- console.log('šŸ“‹ Skipping iOS framework check (not on macOS)');
185
179
  }
186
180
 
187
181
  console.log('šŸ“‹ Checking Android libraries...');
@@ -196,15 +190,12 @@ function verifyAllFiles() {
196
190
  for (const lib of androidLibs) {
197
191
  const libPath = path.join(packageRoot, lib);
198
192
  if (fs.existsSync(libPath)) {
199
- console.log(` āœ… ${lib}`);
200
193
  androidLibsPresent++;
201
- } else {
202
- console.log(` āš ļø Missing: ${lib}`);
203
194
  }
204
195
  }
205
196
 
206
197
  if (androidLibsPresent === 0) {
207
- console.log(' āš ļø No Android libraries found (may be due to missing NDK)');
198
+ console.log(' āš ļø Android libraries not built yet (may be due to missing NDK)');
208
199
  } else {
209
200
  console.log(` āœ… Found ${androidLibsPresent}/${androidLibs.length} Android libraries`);
210
201
  }
@@ -214,9 +205,9 @@ function verifyAllFiles() {
214
205
 
215
206
  async function main() {
216
207
  // 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.');
208
+ if (process.env.CI && !process.env.BUILD_NATIVE_LIBS) {
209
+ console.log('āš ļø Skipping native library builds in CI environment.');
210
+ console.log(' Set BUILD_NATIVE_LIBS=1 to force builds in CI.');
220
211
  process.exit(0);
221
212
  }
222
213
 
@@ -228,12 +219,27 @@ async function main() {
228
219
  process.exit(1);
229
220
  }
230
221
 
222
+ // Check if Rust source is included
223
+ if (!fs.existsSync(ddkFfiRoot)) {
224
+ console.error('āŒ Rust source not found in package!');
225
+ console.error(` Expected at: ${ddkFfiRoot}`);
226
+ console.error(' This indicates a problem with the NPM package.');
227
+ process.exit(1);
228
+ }
229
+
231
230
  // Verify source files are present (should be included in NPM package)
232
231
  const sourceFiles = [
233
232
  'src/ddk_ffi.ts',
234
233
  'src/ddk_ffi-ffi.ts',
234
+ 'src/NativeDdkRn.ts',
235
+ 'src/index.tsx',
235
236
  'cpp/ddk_ffi.hpp',
236
- 'cpp/ddk_ffi.cpp'
237
+ 'cpp/ddk_ffi.cpp',
238
+ 'cpp/bennyblader-ddk-rn.cpp',
239
+ 'cpp/bennyblader-ddk-rn.h',
240
+ 'ddk-ffi/Cargo.toml',
241
+ 'ddk-ffi/src/lib.rs',
242
+ 'ddk-ffi/src/ddk_ffi.udl'
237
243
  ];
238
244
 
239
245
  console.log('šŸ” Checking source files...');
@@ -248,9 +254,10 @@ async function main() {
248
254
  console.log('āœ… All source files present');
249
255
 
250
256
  try {
251
- // Generate turbo module and build native libraries from existing JSI bindings
252
- generateTurboModule();
257
+ // Fix include path if needed
253
258
  fixCppIncludePath();
259
+
260
+ // Build native libraries only (turbo module already generated)
254
261
  buildIOS();
255
262
  buildAndroid();
256
263
 
@@ -263,7 +270,7 @@ async function main() {
263
270
  process.exit(1);
264
271
  }
265
272
 
266
- console.log('\nāœ… All files installed successfully!');
273
+ console.log('\nāœ… Installation completed successfully!');
267
274
  console.log('šŸŽ‰ DDK-RN is ready to use!\n');
268
275
 
269
276
  } catch (error) {
@@ -273,6 +280,7 @@ async function main() {
273
280
  console.error(' - Missing uniffi-bindgen-react-native (install globally)');
274
281
  console.error(' - Missing Android NDK (for Android builds)');
275
282
  console.error(' - Missing Xcode/iOS toolchain (for iOS builds on macOS)');
283
+ console.error(' - Missing Rust toolchain');
276
284
  console.error('');
277
285
  console.error('Report issues at: https://github.com/bennyhodl/ddk-ffi/issues');
278
286
  process.exit(1);
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execSync } = require('child_process');
6
+
7
+ const ddkRnRoot = path.join(__dirname, '..');
8
+ const projectRoot = path.join(ddkRnRoot, '..');
9
+ const ddkFfiSource = path.join(projectRoot, 'ddk-ffi');
10
+ const ddkFfiDest = path.join(ddkRnRoot, 'ddk-ffi');
11
+
12
+ console.log('šŸ“¦ Preparing Rust source for npm package...');
13
+
14
+ function copyDirectory(src, dest) {
15
+ // Remove existing destination if it exists
16
+ if (fs.existsSync(dest)) {
17
+ console.log(`šŸ—‘ļø Removing existing ${path.basename(dest)}...`);
18
+ execSync(`rm -rf "${dest}"`, { stdio: 'inherit' });
19
+ }
20
+
21
+ // Create destination directory
22
+ fs.mkdirSync(dest, { recursive: true });
23
+
24
+ // Copy all files except target directory
25
+ console.log(`šŸ“‹ Copying ${path.basename(src)} to ${path.basename(dest)}...`);
26
+ execSync(`rsync -av --exclude=target/ --exclude=.git/ "${src}/" "${dest}/"`, {
27
+ stdio: 'inherit'
28
+ });
29
+ }
30
+
31
+ function main() {
32
+ try {
33
+ // Check if source exists
34
+ if (!fs.existsSync(ddkFfiSource)) {
35
+ console.error(`āŒ Source directory not found: ${ddkFfiSource}`);
36
+ process.exit(1);
37
+ }
38
+
39
+ // Copy the Rust source
40
+ copyDirectory(ddkFfiSource, ddkFfiDest);
41
+
42
+ console.log('āœ… Rust source prepared for npm package');
43
+ console.log(`šŸ“ Location: ${ddkFfiDest}`);
44
+
45
+ } catch (error) {
46
+ console.error('āŒ Failed to prepare Rust source:', error.message);
47
+ process.exit(1);
48
+ }
49
+ }
50
+
51
+ main();
@@ -0,0 +1,10 @@
1
+ // Generated by uniffi-bindgen-react-native
2
+ import type { TurboModule } from 'react-native';
3
+ import { TurboModuleRegistry } from 'react-native';
4
+
5
+ export interface Spec extends TurboModule {
6
+ installRustCrate(): boolean;
7
+ cleanupRustCrate(): boolean;
8
+ }
9
+
10
+ export default TurboModuleRegistry.getEnforcing<Spec>('DdkRn');
package/src/index.tsx ADDED
@@ -0,0 +1,41 @@
1
+ // Generated by uniffi-bindgen-react-native
2
+ import installer from './NativeDdkRn';
3
+
4
+ // Register the rust crate with Hermes
5
+ // - the boolean flag ensures this loads exactly once, even if the JS
6
+ // code is reloaded (e.g. during development with metro).
7
+ let rustInstalled = false;
8
+ if (!rustInstalled) {
9
+ installer.installRustCrate();
10
+ rustInstalled = true;
11
+ }
12
+
13
+ // Export the generated bindings to the app.
14
+ export * from './/ddk_ffi';
15
+
16
+ // Now import the bindings so we can:
17
+ // - intialize them
18
+ // - export them as namespaced objects as the default export.
19
+ import * as ddk_ffi from './/ddk_ffi';
20
+
21
+ // Initialize the generated bindings: mostly checksums, but also callbacks.
22
+ // - the boolean flag ensures this loads exactly once, even if the JS code
23
+ // is reloaded (e.g. during development with metro).
24
+ let initialized = false;
25
+ if (!initialized) {
26
+ ddk_ffi.default.initialize();
27
+ initialized = true;
28
+ }
29
+
30
+ // This provides parity with the index.web.ts version of this file.
31
+ // The web version relies on an asynchronous fetch, which this doesn't
32
+ // need, so we just no-op.
33
+ export async function uniffiInitAsync() {
34
+ // NOOP.
35
+ }
36
+
37
+ // Export the crates as individually namespaced objects.
38
+ export default {
39
+ ddk_ffi,
40
+ };
41
+