react-native-ota-hot-update 2.4.0-rc.2 → 2.4.1

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.
Files changed (27) hide show
  1. package/README.md +71 -0
  2. package/android/generated/java/com/otahotupdate/NativeOtaHotUpdateSpec.java +4 -0
  3. package/android/generated/jni/RNOtaHotUpdateSpec-generated.cpp +6 -0
  4. package/android/generated/jni/react/renderer/components/RNOtaHotUpdateSpec/RNOtaHotUpdateSpecJSI-generated.cpp +9 -0
  5. package/android/generated/jni/react/renderer/components/RNOtaHotUpdateSpec/RNOtaHotUpdateSpecJSI.h +9 -0
  6. package/android/src/main/java/com/otahotupdate/OtaHotUpdateModule.kt +66 -16
  7. package/android/src/oldarch/OtaHotUpdateSpec.kt +1 -0
  8. package/ios/OtaHotUpdate.mm +85 -42
  9. package/ios/generated/RNOtaHotUpdateSpec/RNOtaHotUpdateSpec-generated.mm +7 -0
  10. package/ios/generated/RNOtaHotUpdateSpec/RNOtaHotUpdateSpec.h +5 -0
  11. package/ios/generated/RNOtaHotUpdateSpecJSI-generated.cpp +9 -0
  12. package/ios/generated/RNOtaHotUpdateSpecJSI.h +9 -0
  13. package/lib/commonjs/NativeOtaHotUpdate.js.map +1 -1
  14. package/lib/commonjs/gits/helper/fs.js +28 -2
  15. package/lib/commonjs/gits/helper/fs.js.map +1 -1
  16. package/lib/module/NativeOtaHotUpdate.js.map +1 -1
  17. package/lib/module/gits/helper/fs.js +28 -2
  18. package/lib/module/gits/helper/fs.js.map +1 -1
  19. package/lib/typescript/commonjs/src/NativeOtaHotUpdate.d.ts +1 -0
  20. package/lib/typescript/commonjs/src/NativeOtaHotUpdate.d.ts.map +1 -1
  21. package/lib/typescript/commonjs/src/gits/helper/fs.d.ts.map +1 -1
  22. package/lib/typescript/module/src/NativeOtaHotUpdate.d.ts +1 -0
  23. package/lib/typescript/module/src/NativeOtaHotUpdate.d.ts.map +1 -1
  24. package/lib/typescript/module/src/gits/helper/fs.d.ts.map +1 -1
  25. package/package.json +1 -1
  26. package/src/NativeOtaHotUpdate.ts +1 -0
  27. package/src/gits/helper/fs.ts +27 -3
package/README.md CHANGED
@@ -8,6 +8,7 @@ This React Native module allows you to manage hot updates (in-app update) with m
8
8
  - Host the bundle on your own server or in a Git repository.
9
9
  - Rollback function
10
10
  - Crash Handling: Handles crash exceptions when an incorrect bundle is updated and will automatically roll back to the previous bundle version.
11
+ - bundle management features
11
12
 
12
13
  1. **Demo via server**
13
14
 
@@ -21,13 +22,35 @@ iOS GIF | Android GIF
21
22
  :-------------------------:|:-------------------------:
22
23
  <img src="./iosgit.gif" title="iOS GIF" width="250"> | <img src="./androidgithotupdate.gif" title="Android GIF" width="250">
23
24
 
25
+ 3. **Demo bundle management**
26
+
27
+ [<img src="https://raw.githubusercontent.com/vantuan88291/react-native-ota-hot-update/e4d4bd928dc096bbb4fc329ce89e80d288e44ff1/ioshotupdate-new.gif" title="iOS Bundle Management Demo" width="300">](https://raw.githubusercontent.com/vantuan88291/react-native-ota-hot-update/e4d4bd928dc096bbb4fc329ce89e80d288e44ff1/ioshotupdate-new.gif)
28
+
24
29
  [![npm downloads](https://img.shields.io/npm/dw/react-native-ota-hot-update)](https://img.shields.io/npm/dw/react-native-ota-hot-update)
25
30
  [![npm package](https://img.shields.io/npm/v/react-native-ota-hot-update?color=red)](https://img.shields.io/npm/v/react-native-ota-hot-update?color=red)
26
31
 
32
+
27
33
  ## New architecture supported
28
34
 
29
35
  New architecture backward compatibility supported from version 2, it also supported old architecture, for source code of version 1.x.x please refer to branch `oldArch`, you might need install version 1.x.x if you are using react native < 0.70
30
36
 
37
+ ### 🚀 Preview Release: Enhanced Bundle Management (v2.4.0-rc.1)
38
+
39
+ We're excited to introduce a preview release with enhanced bundle management features! Version **2.4.0-rc.1** includes:
40
+
41
+ - **Configurable bundle history**: Manage multiple bundle versions (configurable via `maxBundleVersions`)
42
+ - **New APIs**: `getBundleList()`, `deleteBundleById()`, `clearAllBundles()`
43
+ - **Bundle identification**: Descriptive folder names with version and timestamp
44
+ - **Automatic cleanup**: Older bundles are automatically removed when exceeding the limit
45
+
46
+ This is an experimental release for testing. Please try it out and share your feedback! All discussions and issues related to this feature can be found in [PR #132](https://github.com/vantuan88291/react-native-ota-hot-update/pull/132).
47
+ - Branch: `task/manage_bundle`
48
+
49
+ To install the preview version:
50
+ ```bash
51
+ yarn add react-native-ota-hot-update@2.4.0-rc.1
52
+ ```
53
+
31
54
  ## Installation
32
55
 
33
56
  if you don't want to manage the download progress, need to install blob util together:
@@ -228,3 +251,51 @@ Using Strapi, you can build a tailored admin panel to manage React Native hot up
228
251
 
229
252
  ### Sponsor this project
230
253
  https://paypal.me/vantuan88291
254
+
255
+ ---
256
+
257
+ ## Architecture / Sequence Diagram
258
+
259
+ > Paste the content below into [https://sequencediagram.org/](https://sequencediagram.org/) to render the flow diagram.
260
+
261
+ ```
262
+ title react-native-ota-hot-update - Main Flow
263
+
264
+ actor Developer
265
+ participant "Your Server\n(or Git Repo)" as Server
266
+ participant "RN App" as App
267
+ participant "Native Module\n(iOS / Android)" as Native
268
+ participant "Local Storage\n& File System" as Local
269
+
270
+ == Download & Install Update ==
271
+
272
+ Developer->Server: Upload bundle.zip + update.json
273
+ App->Server: Fetch update.json → check new version available
274
+ App->Server: Download bundle.zip
275
+ Server-->App: bundle.zip saved to local path
276
+ App->Native: setupBundlePath(zipPath, version)
277
+ Native->Local: Unzip → output_v{version}_{timestamp}/bundle
278
+ Native->Local: Save bundle PATH to SharedPrefs / UserDefaults
279
+ Native-->App: success
280
+
281
+ alt restartAfterInstall = true
282
+ App->Native: restart()
283
+ end
284
+
285
+ == App Startup - Which Bundle to Load? ==
286
+
287
+ App->Native: getBundle() / bundleJS()
288
+ Native->Local: Read saved PATH
289
+ alt PATH exists AND file on disk AND app version matches
290
+ Native-->App: Use OTA bundle path
291
+ else
292
+ Native-->App: Use default bundle (built-in)
293
+ end
294
+ App->App: Load JS Bundle
295
+
296
+ == Crash Auto-Rollback ==
297
+
298
+ App->App: Crash within 2s of startup
299
+ Native->Local: Restore previous bundle PATH
300
+ Native->App: Restart app with safe bundle
301
+ ```
@@ -80,4 +80,8 @@ public abstract class NativeOtaHotUpdateSpec extends ReactContextBaseJavaModule
80
80
  @ReactMethod
81
81
  @DoNotStrip
82
82
  public abstract void clearAllBundles(double a, Promise promise);
83
+
84
+ @ReactMethod
85
+ @DoNotStrip
86
+ public abstract void writeFile(String path, String base64Content, String encoding, Promise promise);
83
87
  }
@@ -72,6 +72,11 @@ static facebook::jsi::Value __hostFunction_NativeOtaHotUpdateSpecJSI_clearAllBun
72
72
  return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "clearAllBundles", "(DLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
73
73
  }
74
74
 
75
+ static facebook::jsi::Value __hostFunction_NativeOtaHotUpdateSpecJSI_writeFile(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
76
+ static jmethodID cachedMethodId = nullptr;
77
+ return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "writeFile", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
78
+ }
79
+
75
80
  NativeOtaHotUpdateSpecJSI::NativeOtaHotUpdateSpecJSI(const JavaTurboModule::InitParams &params)
76
81
  : JavaTurboModule(params) {
77
82
  methodMap_["setupBundlePath"] = MethodMetadata {5, __hostFunction_NativeOtaHotUpdateSpecJSI_setupBundlePath};
@@ -86,6 +91,7 @@ NativeOtaHotUpdateSpecJSI::NativeOtaHotUpdateSpecJSI(const JavaTurboModule::Init
86
91
  methodMap_["getBundleList"] = MethodMetadata {1, __hostFunction_NativeOtaHotUpdateSpecJSI_getBundleList};
87
92
  methodMap_["deleteBundleById"] = MethodMetadata {1, __hostFunction_NativeOtaHotUpdateSpecJSI_deleteBundleById};
88
93
  methodMap_["clearAllBundles"] = MethodMetadata {1, __hostFunction_NativeOtaHotUpdateSpecJSI_clearAllBundles};
94
+ methodMap_["writeFile"] = MethodMetadata {3, __hostFunction_NativeOtaHotUpdateSpecJSI_writeFile};
89
95
  }
90
96
 
91
97
  std::shared_ptr<TurboModule> RNOtaHotUpdateSpec_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams &params) {
@@ -87,6 +87,14 @@ static jsi::Value __hostFunction_NativeOtaHotUpdateCxxSpecJSI_clearAllBundles(js
87
87
  count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber()
88
88
  );
89
89
  }
90
+ static jsi::Value __hostFunction_NativeOtaHotUpdateCxxSpecJSI_writeFile(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
91
+ return static_cast<NativeOtaHotUpdateCxxSpecJSI *>(&turboModule)->writeFile(
92
+ rt,
93
+ count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt),
94
+ count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asString(rt),
95
+ count <= 2 ? throw jsi::JSError(rt, "Expected argument in position 2 to be passed") : args[2].asString(rt)
96
+ );
97
+ }
90
98
 
91
99
  NativeOtaHotUpdateCxxSpecJSI::NativeOtaHotUpdateCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
92
100
  : TurboModule("OtaHotUpdate", jsInvoker) {
@@ -102,6 +110,7 @@ NativeOtaHotUpdateCxxSpecJSI::NativeOtaHotUpdateCxxSpecJSI(std::shared_ptr<CallI
102
110
  methodMap_["getBundleList"] = MethodMetadata {1, __hostFunction_NativeOtaHotUpdateCxxSpecJSI_getBundleList};
103
111
  methodMap_["deleteBundleById"] = MethodMetadata {1, __hostFunction_NativeOtaHotUpdateCxxSpecJSI_deleteBundleById};
104
112
  methodMap_["clearAllBundles"] = MethodMetadata {1, __hostFunction_NativeOtaHotUpdateCxxSpecJSI_clearAllBundles};
113
+ methodMap_["writeFile"] = MethodMetadata {3, __hostFunction_NativeOtaHotUpdateCxxSpecJSI_writeFile};
105
114
  }
106
115
 
107
116
 
@@ -32,6 +32,7 @@ public:
32
32
  virtual jsi::Value getBundleList(jsi::Runtime &rt, double a) = 0;
33
33
  virtual jsi::Value deleteBundleById(jsi::Runtime &rt, jsi::String id) = 0;
34
34
  virtual jsi::Value clearAllBundles(jsi::Runtime &rt, double a) = 0;
35
+ virtual jsi::Value writeFile(jsi::Runtime &rt, jsi::String path, jsi::String base64Content, jsi::String encoding) = 0;
35
36
 
36
37
  };
37
38
 
@@ -154,6 +155,14 @@ private:
154
155
  return bridging::callFromJs<jsi::Value>(
155
156
  rt, &T::clearAllBundles, jsInvoker_, instance_, std::move(a));
156
157
  }
158
+ jsi::Value writeFile(jsi::Runtime &rt, jsi::String path, jsi::String base64Content, jsi::String encoding) override {
159
+ static_assert(
160
+ bridging::getParameterCount(&T::writeFile) == 4,
161
+ "Expected writeFile(...) to have 4 parameters");
162
+
163
+ return bridging::callFromJs<jsi::Value>(
164
+ rt, &T::writeFile, jsInvoker_, instance_, std::move(path), std::move(base64Content), std::move(encoding));
165
+ }
157
166
 
158
167
  private:
159
168
  friend class NativeOtaHotUpdateCxxSpec;
@@ -22,7 +22,12 @@ import kotlinx.coroutines.SupervisorJob
22
22
  import kotlinx.coroutines.cancel
23
23
  import kotlinx.coroutines.launch
24
24
  import kotlinx.coroutines.withContext
25
+ import android.util.Base64
26
+ import com.facebook.react.bridge.UiThreadUtil
27
+ import java.util.concurrent.Executors
25
28
  import java.io.File
29
+ import java.io.FileOutputStream
30
+ import java.io.IOException
26
31
  import org.json.JSONArray
27
32
  import org.json.JSONObject
28
33
 
@@ -37,6 +42,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
37
42
  OtaHotUpdateSpec(context) {
38
43
  private val utils: Utils = Utils(context)
39
44
  private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
45
+ private val fileWriterExecutor = Executors.newSingleThreadExecutor()
40
46
 
41
47
  override fun getName(): String {
42
48
  return NAME
@@ -45,12 +51,13 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
45
51
  override fun invalidate() {
46
52
  super.invalidate()
47
53
  scope.cancel()
54
+ fileWriterExecutor.shutdown()
48
55
  }
49
56
 
50
57
  private fun loadBundleHistory(): List<BundleVersion> {
51
58
  val sharedPrefs = SharedPrefs(reactApplicationContext)
52
59
  val historyJson = sharedPrefs.getString(BUNDLE_HISTORY)
53
-
60
+
54
61
  // If history exists, load it
55
62
  if (!historyJson.isNullOrEmpty()) {
56
63
  return try {
@@ -68,20 +75,20 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
68
75
  emptyList()
69
76
  }
70
77
  }
71
-
78
+
72
79
  // Migration: If history is empty but PATH exists, migrate from old system
73
80
  val currentPath = sharedPrefs.getString(PATH)
74
81
  val currentVersion = sharedPrefs.getString(VERSION)
75
82
  val previousPath = sharedPrefs.getString(PREVIOUS_PATH)
76
83
  val previousVersion = sharedPrefs.getString(PREVIOUS_VERSION)
77
-
84
+
78
85
  if (currentPath.isNullOrEmpty()) {
79
86
  return emptyList()
80
87
  }
81
-
88
+
82
89
  // Migrate current bundle
83
90
  val migratedHistory = mutableListOf<BundleVersion>()
84
-
91
+
85
92
  // Add current bundle if has version
86
93
  if (!currentVersion.isNullOrEmpty()) {
87
94
  try {
@@ -101,7 +108,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
101
108
  // Version is not a number, skip
102
109
  }
103
110
  }
104
-
111
+
105
112
  // Add previous bundle if exists
106
113
  if (!previousPath.isNullOrEmpty() && !previousVersion.isNullOrEmpty()) {
107
114
  try {
@@ -121,12 +128,12 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
121
128
  // Version is not a number, skip
122
129
  }
123
130
  }
124
-
131
+
125
132
  // Save migrated history if any
126
133
  if (migratedHistory.isNotEmpty()) {
127
134
  saveBundleHistory(migratedHistory.sortedByDescending { it.version })
128
135
  }
129
-
136
+
130
137
  return migratedHistory.sortedByDescending { it.version }
131
138
  }
132
139
 
@@ -204,7 +211,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
204
211
  utils.deleteOldBundleIfneeded(null)
205
212
  val sharedPrefs = SharedPrefs(reactApplicationContext)
206
213
  val oldPath = sharedPrefs.getString(PATH)
207
-
214
+
208
215
  // If version is provided, save to history system
209
216
  if (version != null) {
210
217
  val maxVersionsToKeep = maxVersions ?: Common.DEFAULT_MAX_BUNDLE_VERSIONS
@@ -213,7 +220,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
213
220
  // No version (e.g., Git update) - just set path, no history
214
221
  sharedPrefs.putString(PATH, fileUnzip)
215
222
  }
216
-
223
+
217
224
  sharedPrefs.putString(
218
225
  CURRENT_VERSION_CODE,
219
226
  reactApplicationContext.getVersionCode()
@@ -254,21 +261,21 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
254
261
  try {
255
262
  val sharedPrefs = SharedPrefs(reactApplicationContext)
256
263
  val currentPath = sharedPrefs.getString(PATH)
257
-
264
+
258
265
  // Delete current bundle from file system
259
266
  val isDeleted = utils.deleteOldBundleIfneeded(PATH)
260
-
267
+
261
268
  // Remove current bundle from history if exists
262
269
  if (currentPath != null && currentPath.isNotEmpty()) {
263
270
  val history = loadBundleHistory()
264
271
  val updatedHistory = history.filter { it.path != currentPath }
265
272
  saveBundleHistory(updatedHistory)
266
273
  }
267
-
274
+
268
275
  // Clear paths and version (no longer clear PREVIOUS_PATH, use history instead)
269
276
  sharedPrefs.putString(PATH, "")
270
277
  sharedPrefs.putString(VERSION, "0")
271
-
278
+
272
279
  withContext(Dispatchers.Main) {
273
280
  promise.resolve(isDeleted)
274
281
  }
@@ -282,7 +289,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
282
289
 
283
290
  @ReactMethod
284
291
  override fun restart() {
285
- val context: Context? = currentActivity
292
+ val context: Context? = reactApplicationContext.currentActivity
286
293
  ProcessPhoenix.triggerRebirth(context)
287
294
  }
288
295
 
@@ -364,7 +371,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
364
371
  if (isDeleted) {
365
372
  sharedPrefs.putString(PATH, previousBundle.path)
366
373
  sharedPrefs.putString(VERSION, previousBundle.version.toString())
367
-
374
+
368
375
  withContext(Dispatchers.Main) {
369
376
  promise.resolve(true)
370
377
  }
@@ -509,6 +516,49 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
509
516
  }
510
517
  }
511
518
  }
519
+ /**
520
+ * Write file with base64 content on native thread
521
+ * This runs on a background thread, not blocking JS thread
522
+ */
523
+ @ReactMethod
524
+ override fun writeFile(path: String?, base64Content: String?, encoding: String?, promise: Promise) {
525
+ if (path == null || base64Content == null) {
526
+ promise.reject("INVALID_ARG", "Path and base64Content are required", null)
527
+ return
528
+ }
529
+
530
+ fileWriterExecutor.execute {
531
+ try {
532
+ // Decode base64 to bytes
533
+ val bytes = Base64.decode(base64Content, Base64.DEFAULT)
534
+
535
+ // Ensure parent directory exists
536
+ val file = File(path)
537
+ val parentDir = file.parentFile
538
+ if (parentDir != null && !parentDir.exists()) {
539
+ parentDir.mkdirs()
540
+ }
541
+
542
+ // Write file on background thread
543
+ FileOutputStream(file).use { fos ->
544
+ fos.write(bytes)
545
+ fos.flush()
546
+ }
547
+
548
+ // Resolve on UI thread (React Native requirement)
549
+ UiThreadUtil.runOnUiThread {
550
+ promise.resolve(true)
551
+ }
552
+ } catch (e: IOException) {
553
+ UiThreadUtil.runOnUiThread {
554
+ promise.reject("WRITE_ERROR", "Failed to write file: ${e.message}", e)
555
+ }
556
+ } catch (e: Exception) {
557
+ UiThreadUtil.runOnUiThread {
558
+ promise.reject("WRITE_ERROR", "Unexpected error: ${e.message}", e)
559
+ }
560
+ }
561
+ }
512
562
  }
513
563
 
514
564
  companion object {
@@ -19,4 +19,5 @@ abstract class OtaHotUpdateSpec internal constructor(context: ReactApplicationCo
19
19
  abstract fun getBundleList(a: Double, promise: Promise)
20
20
  abstract fun deleteBundleById(id: String, promise: Promise)
21
21
  abstract fun clearAllBundles(a: Double, promise: Promise)
22
+ abstract fun writeFile(path: String?, base64Content: String?, encoding: String?, promise: Promise)
22
23
  }
@@ -14,6 +14,9 @@ static BOOL isBeginning = YES;
14
14
  @implementation OtaHotUpdate
15
15
  RCT_EXPORT_MODULE()
16
16
 
17
+ + (BOOL)requiresMainQueueSetup {
18
+ return NO;
19
+ }
17
20
 
18
21
  - (instancetype)init {
19
22
  self = [super init];
@@ -237,7 +240,7 @@ void OTAExceptionHandler(NSException *exception) {
237
240
  [dateFormatter setDateFormat:@"yyyy_MM_dd_HH_mm"];
238
241
  [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
239
242
  NSString *timestamp = [dateFormatter stringFromDate:[NSDate date]];
240
- NSString *folderName = version != nil
243
+ NSString *folderName = version != nil
241
244
  ? [NSString stringWithFormat:@"output_v%@_%@", version, timestamp]
242
245
  : [NSString stringWithFormat:@"output_%@", timestamp];
243
246
  NSString *newFolderPath = [directoryPath stringByAppendingPathComponent:folderName];
@@ -303,7 +306,7 @@ RCT_EXPORT_METHOD(setupBundlePath:(NSString *)path extension:(NSString *)extensi
303
306
  if (extractedFilePath) {
304
307
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
305
308
  NSString *oldPath = [defaults stringForKey:@"PATH"];
306
-
309
+
307
310
  // If version is provided, save to history system
308
311
  if (version != nil) {
309
312
  // Default maxVersions to 2 if not provided (backward compatible)
@@ -314,7 +317,7 @@ RCT_EXPORT_METHOD(setupBundlePath:(NSString *)path extension:(NSString *)extensi
314
317
  // No version (e.g., Git update) - just set path, no history
315
318
  [defaults setObject:extractedFilePath forKey:@"PATH"];
316
319
  }
317
-
320
+
318
321
  [defaults setObject:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] forKey:@"VERSION_NAME"];
319
322
  [defaults synchronize];
320
323
  isBeginning = YES;
@@ -331,10 +334,10 @@ RCT_EXPORT_METHOD(deleteBundle:(double)i
331
334
  reject:(RCTPromiseRejectBlock)reject) {
332
335
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
333
336
  NSString *currentPath = [defaults stringForKey:@"PATH"];
334
-
337
+
335
338
  // Delete current bundle from file system
336
339
  BOOL isDeleted = [OtaHotUpdate removeBundleIfNeeded:@"PATH"];
337
-
340
+
338
341
  // Remove current bundle from history if exists
339
342
  if (currentPath && currentPath.length > 0) {
340
343
  NSArray *history = [self loadBundleHistory];
@@ -346,12 +349,12 @@ RCT_EXPORT_METHOD(deleteBundle:(double)i
346
349
  }
347
350
  [self saveBundleHistory:updatedHistory];
348
351
  }
349
-
352
+
350
353
  // Clear paths and version
351
354
  [defaults removeObjectForKey:@"PATH"];
352
355
  [defaults setObject:@"0" forKey:@"VERSION"];
353
356
  [defaults synchronize];
354
-
357
+
355
358
  resolve(@(isDeleted));
356
359
  }
357
360
  // Expose deleteBundle method to JavaScript
@@ -360,7 +363,7 @@ RCT_EXPORT_METHOD(rollbackToPreviousBundle:(double)i
360
363
  reject:(RCTPromiseRejectBlock)reject) {
361
364
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
362
365
  NSString *currentPath = [defaults stringForKey:@"PATH"];
363
-
366
+
364
367
  // Use history to find previous version
365
368
  NSArray *history = [self loadBundleHistory];
366
369
  if (history.count > 0 && currentPath && currentPath.length > 0) {
@@ -372,7 +375,7 @@ RCT_EXPORT_METHOD(rollbackToPreviousBundle:(double)i
372
375
  break;
373
376
  }
374
377
  }
375
-
378
+
376
379
  if (currentBundle) {
377
380
  // Find previous version (older than current, max version)
378
381
  NSDictionary *previousBundle = nil;
@@ -385,7 +388,7 @@ RCT_EXPORT_METHOD(rollbackToPreviousBundle:(double)i
385
388
  }
386
389
  }
387
390
  }
388
-
391
+
389
392
  if (previousBundle && [OtaHotUpdate isFilePathValid:previousBundle[@"path"]]) {
390
393
  // Rollback to previous bundle from history
391
394
  BOOL isDeleted = [OtaHotUpdate removeBundleIfNeeded:@"PATH"];
@@ -399,7 +402,7 @@ RCT_EXPORT_METHOD(rollbackToPreviousBundle:(double)i
399
402
  }
400
403
  }
401
404
  }
402
-
405
+
403
406
  resolve(@(NO));
404
407
  }
405
408
 
@@ -478,7 +481,7 @@ RCT_EXPORT_METHOD(setExactBundlePath:(NSString *)path
478
481
  - (NSArray *)loadBundleHistory {
479
482
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
480
483
  NSString *historyJson = [defaults stringForKey:@"BUNDLE_HISTORY"];
481
-
484
+
482
485
  // If history exists, load it
483
486
  if (historyJson && historyJson.length > 0) {
484
487
  NSData *data = [historyJson dataUsingEncoding:NSUTF8StringEncoding];
@@ -488,20 +491,20 @@ RCT_EXPORT_METHOD(setExactBundlePath:(NSString *)path
488
491
  return history;
489
492
  }
490
493
  }
491
-
494
+
492
495
  // Migration: If history is empty but PATH exists, migrate from old system
493
496
  NSString *currentPath = [defaults stringForKey:@"PATH"];
494
497
  NSString *currentVersion = [defaults stringForKey:@"VERSION"];
495
498
  NSString *previousPath = [defaults stringForKey:@"OLD_PATH"];
496
499
  NSString *previousVersion = [defaults stringForKey:@"PREVIOUS_VERSION"];
497
-
500
+
498
501
  if (!currentPath || currentPath.length == 0) {
499
502
  return @[];
500
503
  }
501
-
504
+
502
505
  // Migrate current bundle
503
506
  NSMutableArray *migratedHistory = [NSMutableArray array];
504
-
507
+
505
508
  // Add current bundle if has version
506
509
  if (currentVersion && currentVersion.length > 0) {
507
510
  NSInteger version = [currentVersion integerValue];
@@ -510,7 +513,7 @@ RCT_EXPORT_METHOD(setExactBundlePath:(NSString *)path
510
513
  NSDictionary *attributes = [fileManager attributesOfItemAtPath:currentPath error:nil];
511
514
  NSDate *modificationDate = attributes[NSFileModificationDate];
512
515
  long long timestamp = modificationDate ? (long long)([modificationDate timeIntervalSince1970] * 1000) : (long long)([[NSDate date] timeIntervalSince1970] * 1000);
513
-
516
+
514
517
  NSMutableDictionary *bundle = [NSMutableDictionary dictionary];
515
518
  bundle[@"version"] = @(version);
516
519
  bundle[@"path"] = currentPath;
@@ -519,7 +522,7 @@ RCT_EXPORT_METHOD(setExactBundlePath:(NSString *)path
519
522
  [migratedHistory addObject:bundle];
520
523
  }
521
524
  }
522
-
525
+
523
526
  // Add previous bundle if exists
524
527
  if (previousPath && previousPath.length > 0 && previousVersion && previousVersion.length > 0) {
525
528
  NSInteger version = [previousVersion integerValue];
@@ -528,7 +531,7 @@ RCT_EXPORT_METHOD(setExactBundlePath:(NSString *)path
528
531
  NSDictionary *attributes = [fileManager attributesOfItemAtPath:previousPath error:nil];
529
532
  NSDate *modificationDate = attributes[NSFileModificationDate];
530
533
  long long timestamp = modificationDate ? (long long)([modificationDate timeIntervalSince1970] * 1000) : (long long)([[NSDate date] timeIntervalSince1970] * 1000);
531
-
534
+
532
535
  NSMutableDictionary *bundle = [NSMutableDictionary dictionary];
533
536
  bundle[@"version"] = @(version);
534
537
  bundle[@"path"] = previousPath;
@@ -537,7 +540,7 @@ RCT_EXPORT_METHOD(setExactBundlePath:(NSString *)path
537
540
  [migratedHistory addObject:bundle];
538
541
  }
539
542
  }
540
-
543
+
541
544
  // Save migrated history if any
542
545
  if (migratedHistory.count > 0) {
543
546
  // Sort by version descending
@@ -551,7 +554,7 @@ RCT_EXPORT_METHOD(setExactBundlePath:(NSString *)path
551
554
  [self saveBundleHistory:sortedHistory];
552
555
  return sortedHistory;
553
556
  }
554
-
557
+
555
558
  return @[];
556
559
  }
557
560
 
@@ -573,7 +576,7 @@ RCT_EXPORT_METHOD(setExactBundlePath:(NSString *)path
573
576
  - (void)saveBundleVersion:(NSString *)path version:(NSInteger)version maxVersions:(NSInteger)maxVersions metadata:(NSString *)metadata {
574
577
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
575
578
  NSArray *history = [self loadBundleHistory];
576
-
579
+
577
580
  // Create new bundle entry
578
581
  NSMutableDictionary *newBundle = [NSMutableDictionary dictionary];
579
582
  newBundle[@"version"] = @(version);
@@ -582,11 +585,11 @@ RCT_EXPORT_METHOD(setExactBundlePath:(NSString *)path
582
585
  if (metadata) {
583
586
  newBundle[@"metadata"] = metadata;
584
587
  }
585
-
588
+
586
589
  // Combine with existing history
587
590
  NSMutableArray *updatedHistory = [NSMutableArray arrayWithObject:newBundle];
588
591
  [updatedHistory addObjectsFromArray:history];
589
-
592
+
590
593
  // Sort by version descending and remove duplicates
591
594
  [updatedHistory sortUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
592
595
  NSInteger v1 = [obj1[@"version"] integerValue];
@@ -595,7 +598,7 @@ RCT_EXPORT_METHOD(setExactBundlePath:(NSString *)path
595
598
  if (v1 < v2) return NSOrderedDescending;
596
599
  return NSOrderedSame;
597
600
  }];
598
-
601
+
599
602
  // Remove duplicates by version
600
603
  NSMutableArray *uniqueHistory = [NSMutableArray array];
601
604
  NSMutableSet *seenVersions = [NSMutableSet set];
@@ -606,25 +609,25 @@ RCT_EXPORT_METHOD(setExactBundlePath:(NSString *)path
606
609
  [uniqueHistory addObject:bundle];
607
610
  }
608
611
  }
609
-
612
+
610
613
  // Keep only maxVersions most recent
611
614
  NSArray *finalHistory = [uniqueHistory subarrayWithRange:NSMakeRange(0, MIN(maxVersions, uniqueHistory.count))];
612
-
615
+
613
616
  // Delete old versions beyond limit
614
617
  NSMutableSet *versionsToKeep = [NSMutableSet set];
615
618
  for (NSDictionary *bundle in finalHistory) {
616
619
  [versionsToKeep addObject:bundle[@"version"]];
617
620
  }
618
-
621
+
619
622
  for (NSDictionary *bundle in uniqueHistory) {
620
623
  if (![versionsToKeep containsObject:bundle[@"version"]]) {
621
624
  [OtaHotUpdate deleteBundleAtPath:bundle[@"path"]];
622
625
  }
623
626
  }
624
-
627
+
625
628
  // Save updated history
626
629
  [self saveBundleHistory:finalHistory];
627
-
630
+
628
631
  // Set current path and version
629
632
  [defaults setObject:path forKey:@"PATH"];
630
633
  [defaults setObject:[NSString stringWithFormat:@"%ld", (long)version] forKey:@"VERSION"];
@@ -649,7 +652,7 @@ RCT_EXPORT_METHOD(getBundleList:(double)a
649
652
  NSArray *history = [self loadBundleHistory];
650
653
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
651
654
  NSString *activePath = [defaults stringForKey:@"PATH"];
652
-
655
+
653
656
  NSMutableArray *bundleList = [NSMutableArray array];
654
657
  for (NSDictionary *bundle in history) {
655
658
  NSString *path = bundle[@"path"];
@@ -669,7 +672,7 @@ RCT_EXPORT_METHOD(getBundleList:(double)a
669
672
  }
670
673
  [bundleList addObject:bundleInfo];
671
674
  }
672
-
675
+
673
676
  NSError *error = nil;
674
677
  NSData *data = [NSJSONSerialization dataWithJSONObject:bundleList options:0 error:&error];
675
678
  if (!error && data) {
@@ -686,7 +689,7 @@ RCT_EXPORT_METHOD(deleteBundleById:(NSString *)id
686
689
  NSArray *history = [self loadBundleHistory];
687
690
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
688
691
  NSString *activePath = [defaults stringForKey:@"PATH"];
689
-
692
+
690
693
  NSDictionary *bundleToDelete = nil;
691
694
  for (NSDictionary *bundle in history) {
692
695
  NSString *folderName = [self extractFolderName:bundle[@"path"]];
@@ -695,12 +698,12 @@ RCT_EXPORT_METHOD(deleteBundleById:(NSString *)id
695
698
  break;
696
699
  }
697
700
  }
698
-
701
+
699
702
  if (!bundleToDelete) {
700
703
  resolve(@(NO));
701
704
  return;
702
705
  }
703
-
706
+
704
707
  // If deleting active bundle, rollback to oldest remaining bundle or clear
705
708
  if ([bundleToDelete[@"path"] isEqualToString:activePath]) {
706
709
  NSMutableArray *remainingBundles = [NSMutableArray array];
@@ -725,10 +728,10 @@ RCT_EXPORT_METHOD(deleteBundleById:(NSString *)id
725
728
  }
726
729
  [defaults synchronize];
727
730
  }
728
-
731
+
729
732
  // Delete bundle folder
730
733
  BOOL isDeleted = [OtaHotUpdate deleteBundleAtPath:bundleToDelete[@"path"]];
731
-
734
+
732
735
  // Remove from history
733
736
  NSMutableArray *updatedHistory = [NSMutableArray array];
734
737
  for (NSDictionary *bundle in history) {
@@ -737,7 +740,7 @@ RCT_EXPORT_METHOD(deleteBundleById:(NSString *)id
737
740
  }
738
741
  }
739
742
  [self saveBundleHistory:updatedHistory];
740
-
743
+
741
744
  resolve(@(isDeleted));
742
745
  }
743
746
 
@@ -746,23 +749,63 @@ RCT_EXPORT_METHOD(clearAllBundles:(double)a
746
749
  reject:(RCTPromiseRejectBlock)reject) {
747
750
  NSArray *history = [self loadBundleHistory];
748
751
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
749
-
752
+
750
753
  // Delete all bundle folders
751
754
  for (NSDictionary *bundle in history) {
752
755
  [OtaHotUpdate deleteBundleAtPath:bundle[@"path"]];
753
756
  }
754
-
757
+
755
758
  // Clear history
756
759
  [self saveBundleHistory:@[]];
757
-
760
+
758
761
  // Clear current path and version
759
762
  [defaults removeObjectForKey:@"PATH"];
760
763
  [defaults removeObjectForKey:@"VERSION"];
761
764
  [defaults synchronize];
762
-
765
+
763
766
  resolve(@(YES));
764
767
  }
765
768
 
769
+ RCT_EXPORT_METHOD(writeFile:(NSString *)path
770
+ base64Content:(NSString *)base64Content
771
+ encoding:(NSString *)encoding
772
+ resolve:(RCTPromiseResolveBlock)resolve
773
+ reject:(RCTPromiseRejectBlock)reject) {
774
+ // Run on background queue to avoid blocking JS thread
775
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
776
+ @try {
777
+ // Decode base64 to NSData
778
+ NSData *data = [[NSData alloc] initWithBase64EncodedString:base64Content options:0];
779
+ if (!data) {
780
+ reject(@"DECODE_ERROR", @"Failed to decode base64 content", nil);
781
+ return;
782
+ }
783
+
784
+ // Ensure parent directory exists
785
+ NSString *parentDir = [path stringByDeletingLastPathComponent];
786
+ NSFileManager *fileManager = [NSFileManager defaultManager];
787
+ if (![fileManager fileExistsAtPath:parentDir]) {
788
+ NSError *error;
789
+ if (![fileManager createDirectoryAtPath:parentDir withIntermediateDirectories:YES attributes:nil error:&error]) {
790
+ reject(@"CREATE_DIR_ERROR", [NSString stringWithFormat:@"Failed to create directory: %@", error.localizedDescription], error);
791
+ return;
792
+ }
793
+ }
794
+
795
+ // Write file on background thread
796
+ NSError *error;
797
+ if (![data writeToFile:path options:NSDataWritingAtomic error:&error]) {
798
+ reject(@"WRITE_ERROR", [NSString stringWithFormat:@"Failed to write file: %@", error.localizedDescription], error);
799
+ return;
800
+ }
801
+
802
+ resolve(@(YES));
803
+ } @catch (NSException *exception) {
804
+ reject(@"WRITE_ERROR", [NSString stringWithFormat:@"Unexpected error: %@", exception.reason], nil);
805
+ }
806
+ });
807
+ }
808
+
766
809
  // Don't compile this code when we build for the old architecture.
767
810
  #ifdef RCT_NEW_ARCH_ENABLED
768
811
  - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
@@ -74,6 +74,10 @@ namespace facebook::react {
74
74
  return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "clearAllBundles", @selector(clearAllBundles:resolve:reject:), args, count);
75
75
  }
76
76
 
77
+ static facebook::jsi::Value __hostFunction_NativeOtaHotUpdateSpecJSI_writeFile(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
78
+ return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "writeFile", @selector(writeFile:base64Content:encoding:resolve:reject:), args, count);
79
+ }
80
+
77
81
  NativeOtaHotUpdateSpecJSI::NativeOtaHotUpdateSpecJSI(const ObjCTurboModule::InitParams &params)
78
82
  : ObjCTurboModule(params) {
79
83
 
@@ -112,5 +116,8 @@ namespace facebook::react {
112
116
 
113
117
  methodMap_["clearAllBundles"] = MethodMetadata {1, __hostFunction_NativeOtaHotUpdateSpecJSI_clearAllBundles};
114
118
 
119
+
120
+ methodMap_["writeFile"] = MethodMetadata {3, __hostFunction_NativeOtaHotUpdateSpecJSI_writeFile};
121
+
115
122
  }
116
123
  } // namespace facebook::react
@@ -71,6 +71,11 @@
71
71
  - (void)clearAllBundles:(double)a
72
72
  resolve:(RCTPromiseResolveBlock)resolve
73
73
  reject:(RCTPromiseRejectBlock)reject;
74
+ - (void)writeFile:(NSString *)path
75
+ base64Content:(NSString *)base64Content
76
+ encoding:(NSString *)encoding
77
+ resolve:(RCTPromiseResolveBlock)resolve
78
+ reject:(RCTPromiseRejectBlock)reject;
74
79
 
75
80
  @end
76
81
 
@@ -87,6 +87,14 @@ static jsi::Value __hostFunction_NativeOtaHotUpdateCxxSpecJSI_clearAllBundles(js
87
87
  count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber()
88
88
  );
89
89
  }
90
+ static jsi::Value __hostFunction_NativeOtaHotUpdateCxxSpecJSI_writeFile(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
91
+ return static_cast<NativeOtaHotUpdateCxxSpecJSI *>(&turboModule)->writeFile(
92
+ rt,
93
+ count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt),
94
+ count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asString(rt),
95
+ count <= 2 ? throw jsi::JSError(rt, "Expected argument in position 2 to be passed") : args[2].asString(rt)
96
+ );
97
+ }
90
98
 
91
99
  NativeOtaHotUpdateCxxSpecJSI::NativeOtaHotUpdateCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
92
100
  : TurboModule("OtaHotUpdate", jsInvoker) {
@@ -102,6 +110,7 @@ NativeOtaHotUpdateCxxSpecJSI::NativeOtaHotUpdateCxxSpecJSI(std::shared_ptr<CallI
102
110
  methodMap_["getBundleList"] = MethodMetadata {1, __hostFunction_NativeOtaHotUpdateCxxSpecJSI_getBundleList};
103
111
  methodMap_["deleteBundleById"] = MethodMetadata {1, __hostFunction_NativeOtaHotUpdateCxxSpecJSI_deleteBundleById};
104
112
  methodMap_["clearAllBundles"] = MethodMetadata {1, __hostFunction_NativeOtaHotUpdateCxxSpecJSI_clearAllBundles};
113
+ methodMap_["writeFile"] = MethodMetadata {3, __hostFunction_NativeOtaHotUpdateCxxSpecJSI_writeFile};
105
114
  }
106
115
 
107
116
 
@@ -32,6 +32,7 @@ public:
32
32
  virtual jsi::Value getBundleList(jsi::Runtime &rt, double a) = 0;
33
33
  virtual jsi::Value deleteBundleById(jsi::Runtime &rt, jsi::String id) = 0;
34
34
  virtual jsi::Value clearAllBundles(jsi::Runtime &rt, double a) = 0;
35
+ virtual jsi::Value writeFile(jsi::Runtime &rt, jsi::String path, jsi::String base64Content, jsi::String encoding) = 0;
35
36
 
36
37
  };
37
38
 
@@ -154,6 +155,14 @@ private:
154
155
  return bridging::callFromJs<jsi::Value>(
155
156
  rt, &T::clearAllBundles, jsInvoker_, instance_, std::move(a));
156
157
  }
158
+ jsi::Value writeFile(jsi::Runtime &rt, jsi::String path, jsi::String base64Content, jsi::String encoding) override {
159
+ static_assert(
160
+ bridging::getParameterCount(&T::writeFile) == 4,
161
+ "Expected writeFile(...) to have 4 parameters");
162
+
163
+ return bridging::callFromJs<jsi::Value>(
164
+ rt, &T::writeFile, jsInvoker_, instance_, std::move(path), std::move(base64Content), std::move(encoding));
165
+ }
157
166
 
158
167
  private:
159
168
  friend class NativeOtaHotUpdateCxxSpec;
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeOtaHotUpdate.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAAmD,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAiBpCC,gCAAmB,CAACC,YAAY,CAAO,cAAc,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeOtaHotUpdate.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAAmD,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAkBpCC,gCAAmB,CAACC,YAAY,CAAO,cAAc,CAAC","ignoreList":[]}
@@ -16,6 +16,17 @@ let RNFS = {
16
16
  try {
17
17
  RNFS = require('react-native-fs');
18
18
  } catch {}
19
+
20
+ // Try to load native OtaHotUpdate module for better performance
21
+ let OtaHotUpdateNative = null;
22
+ try {
23
+ const {
24
+ NativeModules
25
+ } = require('react-native');
26
+ OtaHotUpdateNative = NativeModules.OtaHotUpdate;
27
+ } catch (e) {
28
+ // Native module not available, will fallback to RNFS
29
+ }
19
30
  function Err(name) {
20
31
  return class extends Error {
21
32
  code = name;
@@ -83,12 +94,27 @@ const writeFile = async (path, content, opts) => {
83
94
  encoding = opts.encoding;
84
95
  }
85
96
  if (typeof content === 'string') {
97
+ // Text file - use RNFS (fast enough for text)
86
98
  encoding = encoding || 'utf8';
99
+ await RNFS.writeFile(path, content, encoding);
87
100
  } else {
101
+ // Binary file - try native module first for better performance
88
102
  encoding = 'base64';
89
- content = _buffer.Buffer.from(content).toString('base64');
103
+ const base64Content = _buffer.Buffer.from(content).toString('base64');
104
+ if (OtaHotUpdateNative && OtaHotUpdateNative.writeFile) {
105
+ try {
106
+ // Use native write (runs on native thread, doesn't block JS thread)
107
+ await OtaHotUpdateNative.writeFile(path, base64Content, encoding);
108
+ } catch (e) {
109
+ // Fallback to RNFS if native fails
110
+ console.warn('OtaHotUpdate.writeFile failed, falling back to RNFS:', e);
111
+ await RNFS.writeFile(path, base64Content, encoding);
112
+ }
113
+ } else {
114
+ // No native module available - use RNFS
115
+ await RNFS.writeFile(path, base64Content, encoding);
116
+ }
90
117
  }
91
- await RNFS.writeFile(path, content, encoding);
92
118
  };
93
119
  exports.writeFile = writeFile;
94
120
  const stat = async path => {
@@ -1 +1 @@
1
- {"version":3,"names":["_buffer","require","RNFS","unlink","console","log","readdir","mkdir","readFile","writeFile","stat","Err","name","Error","code","constructor","args","message","ENOENT","ENOTDIR","path","err","exports","opts","encoding","result","Buffer","from","content","toString","r","isSymbolicLink","lstat","rmdir","readlink","symlink","chmod"],"sourceRoot":"../../../../src","sources":["gits/helper/fs.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_buffer","require","RNFS","unlink","console","log","readdir","mkdir","readFile","writeFile","stat","OtaHotUpdateNative","NativeModules","OtaHotUpdate","e","Err","name","Error","code","constructor","args","message","ENOENT","ENOTDIR","path","err","exports","opts","encoding","result","Buffer","from","content","base64Content","toString","warn","r","isSymbolicLink","lstat","rmdir","readlink","symlink","chmod"],"sourceRoot":"../../../../src","sources":["gits/helper/fs.ts"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeOtaHotUpdate.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AAiBlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,cAAc,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeOtaHotUpdate.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AAkBlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,cAAc,CAAC","ignoreList":[]}
@@ -12,6 +12,17 @@ let RNFS = {
12
12
  try {
13
13
  RNFS = require('react-native-fs');
14
14
  } catch {}
15
+
16
+ // Try to load native OtaHotUpdate module for better performance
17
+ let OtaHotUpdateNative = null;
18
+ try {
19
+ const {
20
+ NativeModules
21
+ } = require('react-native');
22
+ OtaHotUpdateNative = NativeModules.OtaHotUpdate;
23
+ } catch (e) {
24
+ // Native module not available, will fallback to RNFS
25
+ }
15
26
  function Err(name) {
16
27
  return class extends Error {
17
28
  code = name;
@@ -76,12 +87,27 @@ export const writeFile = async (path, content, opts) => {
76
87
  encoding = opts.encoding;
77
88
  }
78
89
  if (typeof content === 'string') {
90
+ // Text file - use RNFS (fast enough for text)
79
91
  encoding = encoding || 'utf8';
92
+ await RNFS.writeFile(path, content, encoding);
80
93
  } else {
94
+ // Binary file - try native module first for better performance
81
95
  encoding = 'base64';
82
- content = Buffer.from(content).toString('base64');
96
+ const base64Content = Buffer.from(content).toString('base64');
97
+ if (OtaHotUpdateNative && OtaHotUpdateNative.writeFile) {
98
+ try {
99
+ // Use native write (runs on native thread, doesn't block JS thread)
100
+ await OtaHotUpdateNative.writeFile(path, base64Content, encoding);
101
+ } catch (e) {
102
+ // Fallback to RNFS if native fails
103
+ console.warn('OtaHotUpdate.writeFile failed, falling back to RNFS:', e);
104
+ await RNFS.writeFile(path, base64Content, encoding);
105
+ }
106
+ } else {
107
+ // No native module available - use RNFS
108
+ await RNFS.writeFile(path, base64Content, encoding);
109
+ }
83
110
  }
84
- await RNFS.writeFile(path, content, encoding);
85
111
  };
86
112
  export const stat = async path => {
87
113
  try {
@@ -1 +1 @@
1
- {"version":3,"names":["Buffer","RNFS","unlink","console","log","readdir","mkdir","readFile","writeFile","stat","require","Err","name","Error","code","constructor","args","message","ENOENT","ENOTDIR","path","err","opts","encoding","result","from","content","toString","r","isSymbolicLink","lstat","rmdir","readlink","symlink","chmod"],"sourceRoot":"../../../../src","sources":["gits/helper/fs.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["Buffer","RNFS","unlink","console","log","readdir","mkdir","readFile","writeFile","stat","require","OtaHotUpdateNative","NativeModules","OtaHotUpdate","e","Err","name","Error","code","constructor","args","message","ENOENT","ENOTDIR","path","err","opts","encoding","result","from","content","base64Content","toString","warn","r","isSymbolicLink","lstat","rmdir","readlink","symlink","chmod"],"sourceRoot":"../../../../src","sources":["gits/helper/fs.ts"],"mappings":";;AAAA,SAASA,MAAM,QAAQ,QAAQ;AAE/B,IAAIC,IAAI,GAAG;EACTC,MAAM,EAAEC,OAAO,CAACC,GAAG;EACnBC,OAAO,EAAEF,OAAO,CAACC,GAAG;EACpBE,KAAK,EAAEH,OAAO,CAACC,GAAG;EAClBG,QAAQ,EAAEJ,OAAO,CAACC,GAAG;EACrBI,SAAS,EAAEL,OAAO,CAACC,GAAG;EACtBK,IAAI,EAAEN,OAAO,CAACC;AAChB,CAAC;AACD,IAAI;EACFH,IAAI,GAAGS,OAAO,CAAC,iBAAiB,CAAC;AACnC,CAAC,CAAC,MAAM,CAAC;;AAET;AACA,IAAIC,kBAAuB,GAAG,IAAI;AAClC,IAAI;EACF,MAAM;IAAEC;EAAc,CAAC,GAAGF,OAAO,CAAC,cAAc,CAAC;EACjDC,kBAAkB,GAAGC,aAAa,CAACC,YAAY;AACjD,CAAC,CAAC,OAAOC,CAAC,EAAE;EACV;AAAA;AAGF,SAASC,GAAGA,CAACC,IAAY,EAAE;EACzB,OAAO,cAAcC,KAAK,CAAC;IAClBC,IAAI,GAAGF,IAAI;IAClBG,WAAWA,CAAC,GAAGC,IAAS,EAAE;MACxB,KAAK,CAAC,GAAGA,IAAI,CAAC;MACd,IAAI,IAAI,CAACC,OAAO,EAAE;QAChB,IAAI,CAACA,OAAO,GAAGL,IAAI,GAAG,IAAI,GAAG,IAAI,CAACK,OAAO;MAC3C,CAAC,MAAM;QACL,IAAI,CAACA,OAAO,GAAGL,IAAI;MACrB;IACF;EACF,CAAC;AACH;;AAEA;AACA,MAAMM,MAAM,GAAGP,GAAG,CAAC,QAAQ,CAAC;AAC5B,MAAMQ,OAAO,GAAGR,GAAG,CAAC,SAAS,CAAC;AAC9B;;AAEA,OAAO,MAAMV,OAAO,GAAG,MAAOmB,IAAY,IAAK;EAC7C,IAAI;IACF,OAAO,MAAMvB,IAAI,CAACI,OAAO,CAACmB,IAAI,CAAC;EACjC,CAAC,CAAC,OAAOC,GAAQ,EAAE;IACjB,QAAQA,GAAG,CAACJ,OAAO;MACjB,KAAK,qCAAqC;QAAE;UAC1C,MAAM,IAAIE,OAAO,CAACC,IAAI,CAAC;QACzB;MACA,KAAK,uBAAuB;QAAE;UAC5B,MAAM,IAAIF,MAAM,CAACE,IAAI,CAAC;QACxB;MACA;QACE,MAAMC,GAAG;IACb;EACF;AACF,CAAC;AAED,OAAO,MAAMnB,KAAK,GAAG,MAAOkB,IAAY,IAAK;EAC3C,OAAOvB,IAAI,CAACK,KAAK,CAACkB,IAAI,CAAC;AACzB,CAAC;AAED,OAAO,MAAMjB,QAAQ,GAAG,MAAAA,CACtBiB,IAAY,EACZE,IAAyC,KACtC;EACH,IAAIC,QAAQ;EAEZ,IAAI,OAAOD,IAAI,KAAK,QAAQ,EAAE;IAC5BC,QAAQ,GAAGD,IAAI;EACjB,CAAC,MAAM,IAAI,OAAOA,IAAI,KAAK,QAAQ,EAAE;IACnCC,QAAQ,GAAGD,IAAI,CAACC,QAAQ;EAC1B;;EAEA;EACA,IAAIC,MAA2B,GAAG,MAAM3B,IAAI,CAACM,QAAQ,CACnDiB,IAAI,EACJG,QAAQ,IAAI,QACd,CAAC;EAED,IAAI,CAACA,QAAQ,EAAE;IACb;IACAC,MAAM,GAAG5B,MAAM,CAAC6B,IAAI,CAACD,MAAM,EAAE,QAAQ,CAAC;EACxC;EAEA,OAAOA,MAAM;AACf,CAAC;AACD,OAAO,MAAMpB,SAAS,GAAG,MAAAA,CACvBgB,IAAY,EACZM,OAA4B,EAC5BJ,IAAyC,KACtC;EACH,IAAIC,QAAQ;EAEZ,IAAI,OAAOD,IAAI,KAAK,QAAQ,EAAE;IAC5BC,QAAQ,GAAGD,IAAI;EACjB,CAAC,MAAM,IAAI,OAAOA,IAAI,KAAK,QAAQ,EAAE;IACnCC,QAAQ,GAAGD,IAAI,CAACC,QAAQ;EAC1B;EAEA,IAAI,OAAOG,OAAO,KAAK,QAAQ,EAAE;IAC/B;IACAH,QAAQ,GAAGA,QAAQ,IAAI,MAAM;IAC7B,MAAM1B,IAAI,CAACO,SAAS,CAACgB,IAAI,EAAEM,OAAO,EAAEH,QAAQ,CAAC;EAC/C,CAAC,MAAM;IACL;IACAA,QAAQ,GAAG,QAAQ;IACnB,MAAMI,aAAa,GAAG/B,MAAM,CAAC6B,IAAI,CAACC,OAAO,CAAC,CAACE,QAAQ,CAAC,QAAQ,CAAC;IAE7D,IAAIrB,kBAAkB,IAAIA,kBAAkB,CAACH,SAAS,EAAE;MACtD,IAAI;QACF;QACA,MAAMG,kBAAkB,CAACH,SAAS,CAACgB,IAAI,EAAEO,aAAa,EAAEJ,QAAQ,CAAC;MACnE,CAAC,CAAC,OAAOb,CAAC,EAAE;QACV;QACAX,OAAO,CAAC8B,IAAI,CAAC,sDAAsD,EAAEnB,CAAC,CAAC;QACvE,MAAMb,IAAI,CAACO,SAAS,CAACgB,IAAI,EAAEO,aAAa,EAAEJ,QAAQ,CAAC;MACrD;IACF,CAAC,MAAM;MACL;MACA,MAAM1B,IAAI,CAACO,SAAS,CAACgB,IAAI,EAAEO,aAAa,EAAEJ,QAAQ,CAAC;IACrD;EACF;AACF,CAAC;AAED,OAAO,MAAMlB,IAAI,GAAG,MAAOe,IAAY,IAAK;EAC1C,IAAI;IACF,MAAMU,CAAC,GAAG,MAAMjC,IAAI,CAACQ,IAAI,CAACe,IAAI,CAAC;IAC/B;IACA;IACA;IACAU,CAAC,CAACC,cAAc,GAAG,MAAM,KAAK;IAC9B,OAAOD,CAAC;EACV,CAAC,CAAC,OAAOT,GAAQ,EAAE;IACjB,QAAQA,GAAG,CAACJ,OAAO;MACjB,KAAK,qBAAqB;QAAE;UAC1B,MAAM,IAAIC,MAAM,CAACE,IAAI,CAAC;QACxB;MACA;QACE,MAAMC,GAAG;IACb;EACF;AACF,CAAC;;AAED;AACA,OAAO,MAAMW,KAAK,GAAG3B,IAAI;AAEzB,OAAO,MAAMP,MAAM,GAAG,MAAOsB,IAAY,IAAK;EAC5C,IAAI;IACF,MAAMvB,IAAI,CAACC,MAAM,CAACsB,IAAI,CAAC;EACzB,CAAC,CAAC,OAAOC,GAAQ,EAAE;IACjB,QAAQA,GAAG,CAACJ,OAAO;MACjB,KAAK,qBAAqB;QAAE;UAC1B,MAAM,IAAIC,MAAM,CAACE,IAAI,CAAC;QACxB;MACA;QACE,MAAMC,GAAG;IACb;EACF;AACF,CAAC;;AAED;AACA,OAAO,MAAMY,KAAK,GAAGnC,MAAM;;AAE3B;AACA,OAAO,MAAMoC,QAAQ,GAAG,MAAAA,CAAA,KAAY;EAClC,MAAM,IAAIrB,KAAK,CAAC,iBAAiB,CAAC;AACpC,CAAC;AACD,OAAO,MAAMsB,OAAO,GAAG,MAAAA,CAAA,KAAY;EACjC,MAAM,IAAItB,KAAK,CAAC,iBAAiB,CAAC;AACpC,CAAC;;AAED;AACA;AACA,OAAO,MAAMuB,KAAK,GAAG,MAAAA,CAAA,KAAY;EAC/B,MAAM,IAAIvB,KAAK,CAAC,iBAAiB,CAAC;AACpC,CAAC","ignoreList":[]}
@@ -12,6 +12,7 @@ export interface Spec extends TurboModule {
12
12
  getBundleList(a: number): Promise<string>;
13
13
  deleteBundleById(id: string): Promise<boolean>;
14
14
  clearAllBundles(a: number): Promise<boolean>;
15
+ writeFile(path: string, base64Content: string, encoding: string): Promise<boolean>;
15
16
  }
16
17
  declare const _default: Spec;
17
18
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"NativeOtaHotUpdate.d.ts","sourceRoot":"","sources":["../../../../src/NativeOtaHotUpdate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9H,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,IAAI,IAAI,CAAC;IAChB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,wBAAwB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9C;;AAED,wBAAsE"}
1
+ {"version":3,"file":"NativeOtaHotUpdate.d.ts","sourceRoot":"","sources":["../../../../src/NativeOtaHotUpdate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9H,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,IAAI,IAAI,CAAC;IAChB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,wBAAwB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpF;;AAED,wBAAsE"}
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../../../../../src/gits/helper/fs.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,OAAO,SAAgB,MAAM,kBAezC,CAAC;AAEF,eAAO,MAAM,KAAK,SAAgB,MAAM,kBAEvC,CAAC;AAEF,eAAO,MAAM,QAAQ,SACb,MAAM,SACL,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,kDAsB1C,CAAC;AACF,eAAO,MAAM,SAAS,SACd,MAAM,WACH,MAAM,GAAG,UAAU,SACrB,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,kBAkB1C,CAAC;AAEF,eAAO,MAAM,IAAI,SAAgB,MAAM,kBAiBtC,CAAC;AAGF,eAAO,MAAM,KAAK,SApBe,MAAM,kBAoBd,CAAC;AAE1B,eAAO,MAAM,MAAM,SAAgB,MAAM,kBAYxC,CAAC;AAGF,eAAO,MAAM,KAAK,SAfiB,MAAM,kBAed,CAAC;AAG5B,eAAO,MAAM,QAAQ,sBAEpB,CAAC;AACF,eAAO,MAAM,OAAO,sBAEnB,CAAC;AAIF,eAAO,MAAM,KAAK,sBAEjB,CAAC"}
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../../../../../src/gits/helper/fs.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,OAAO,SAAgB,MAAM,kBAezC,CAAC;AAEF,eAAO,MAAM,KAAK,SAAgB,MAAM,kBAEvC,CAAC;AAEF,eAAO,MAAM,QAAQ,SACb,MAAM,SACL,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,kDAsB1C,CAAC;AACF,eAAO,MAAM,SAAS,SACd,MAAM,WACH,MAAM,GAAG,UAAU,SACrB,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,kBAiC1C,CAAC;AAEF,eAAO,MAAM,IAAI,SAAgB,MAAM,kBAiBtC,CAAC;AAGF,eAAO,MAAM,KAAK,SApBe,MAAM,kBAoBd,CAAC;AAE1B,eAAO,MAAM,MAAM,SAAgB,MAAM,kBAYxC,CAAC;AAGF,eAAO,MAAM,KAAK,SAfiB,MAAM,kBAed,CAAC;AAG5B,eAAO,MAAM,QAAQ,sBAEpB,CAAC;AACF,eAAO,MAAM,OAAO,sBAEnB,CAAC;AAIF,eAAO,MAAM,KAAK,sBAEjB,CAAC"}
@@ -12,6 +12,7 @@ export interface Spec extends TurboModule {
12
12
  getBundleList(a: number): Promise<string>;
13
13
  deleteBundleById(id: string): Promise<boolean>;
14
14
  clearAllBundles(a: number): Promise<boolean>;
15
+ writeFile(path: string, base64Content: string, encoding: string): Promise<boolean>;
15
16
  }
16
17
  declare const _default: Spec;
17
18
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"NativeOtaHotUpdate.d.ts","sourceRoot":"","sources":["../../../../src/NativeOtaHotUpdate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9H,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,IAAI,IAAI,CAAC;IAChB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,wBAAwB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9C;;AAED,wBAAsE"}
1
+ {"version":3,"file":"NativeOtaHotUpdate.d.ts","sourceRoot":"","sources":["../../../../src/NativeOtaHotUpdate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9H,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,IAAI,IAAI,CAAC;IAChB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,wBAAwB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpF;;AAED,wBAAsE"}
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../../../../../src/gits/helper/fs.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,OAAO,SAAgB,MAAM,kBAezC,CAAC;AAEF,eAAO,MAAM,KAAK,SAAgB,MAAM,kBAEvC,CAAC;AAEF,eAAO,MAAM,QAAQ,SACb,MAAM,SACL,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,kDAsB1C,CAAC;AACF,eAAO,MAAM,SAAS,SACd,MAAM,WACH,MAAM,GAAG,UAAU,SACrB,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,kBAkB1C,CAAC;AAEF,eAAO,MAAM,IAAI,SAAgB,MAAM,kBAiBtC,CAAC;AAGF,eAAO,MAAM,KAAK,SApBe,MAAM,kBAoBd,CAAC;AAE1B,eAAO,MAAM,MAAM,SAAgB,MAAM,kBAYxC,CAAC;AAGF,eAAO,MAAM,KAAK,SAfiB,MAAM,kBAed,CAAC;AAG5B,eAAO,MAAM,QAAQ,sBAEpB,CAAC;AACF,eAAO,MAAM,OAAO,sBAEnB,CAAC;AAIF,eAAO,MAAM,KAAK,sBAEjB,CAAC"}
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../../../../../src/gits/helper/fs.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,OAAO,SAAgB,MAAM,kBAezC,CAAC;AAEF,eAAO,MAAM,KAAK,SAAgB,MAAM,kBAEvC,CAAC;AAEF,eAAO,MAAM,QAAQ,SACb,MAAM,SACL,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,kDAsB1C,CAAC;AACF,eAAO,MAAM,SAAS,SACd,MAAM,WACH,MAAM,GAAG,UAAU,SACrB,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,kBAiC1C,CAAC;AAEF,eAAO,MAAM,IAAI,SAAgB,MAAM,kBAiBtC,CAAC;AAGF,eAAO,MAAM,KAAK,SApBe,MAAM,kBAoBd,CAAC;AAE1B,eAAO,MAAM,MAAM,SAAgB,MAAM,kBAYxC,CAAC;AAGF,eAAO,MAAM,KAAK,SAfiB,MAAM,kBAed,CAAC;AAG5B,eAAO,MAAM,QAAQ,sBAEpB,CAAC;AACF,eAAO,MAAM,OAAO,sBAEnB,CAAC;AAIF,eAAO,MAAM,KAAK,sBAEjB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-ota-hot-update",
3
- "version": "2.4.0-rc.2",
3
+ "version": "2.4.1",
4
4
  "description": "Hot update for react native",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/commonjs/index.js",
@@ -14,6 +14,7 @@ export interface Spec extends TurboModule {
14
14
  getBundleList(a: number): Promise<string>;
15
15
  deleteBundleById(id: string): Promise<boolean>;
16
16
  clearAllBundles(a: number): Promise<boolean>;
17
+ writeFile(path: string, base64Content: string, encoding: string): Promise<boolean>;
17
18
  }
18
19
 
19
20
  export default TurboModuleRegistry.getEnforcing<Spec>('OtaHotUpdate');
@@ -12,6 +12,15 @@ try {
12
12
  RNFS = require('react-native-fs');
13
13
  } catch {}
14
14
 
15
+ // Try to load native OtaHotUpdate module for better performance
16
+ let OtaHotUpdateNative: any = null;
17
+ try {
18
+ const { NativeModules } = require('react-native');
19
+ OtaHotUpdateNative = NativeModules.OtaHotUpdate;
20
+ } catch (e) {
21
+ // Native module not available, will fallback to RNFS
22
+ }
23
+
15
24
  function Err(name: string) {
16
25
  return class extends Error {
17
26
  public code = name;
@@ -91,13 +100,28 @@ export const writeFile = async (
91
100
  }
92
101
 
93
102
  if (typeof content === 'string') {
103
+ // Text file - use RNFS (fast enough for text)
94
104
  encoding = encoding || 'utf8';
105
+ await RNFS.writeFile(path, content, encoding);
95
106
  } else {
107
+ // Binary file - try native module first for better performance
96
108
  encoding = 'base64';
97
- content = Buffer.from(content).toString('base64');
109
+ const base64Content = Buffer.from(content).toString('base64');
110
+
111
+ if (OtaHotUpdateNative && OtaHotUpdateNative.writeFile) {
112
+ try {
113
+ // Use native write (runs on native thread, doesn't block JS thread)
114
+ await OtaHotUpdateNative.writeFile(path, base64Content, encoding);
115
+ } catch (e) {
116
+ // Fallback to RNFS if native fails
117
+ console.warn('OtaHotUpdate.writeFile failed, falling back to RNFS:', e);
118
+ await RNFS.writeFile(path, base64Content, encoding);
119
+ }
120
+ } else {
121
+ // No native module available - use RNFS
122
+ await RNFS.writeFile(path, base64Content, encoding);
123
+ }
98
124
  }
99
-
100
- await RNFS.writeFile(path, content as string, encoding);
101
125
  };
102
126
 
103
127
  export const stat = async (path: string) => {