@hot-updater/react-native 0.16.7-0 → 0.18.0

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 (143) hide show
  1. package/HotUpdater.podspec +7 -11
  2. package/android/{generated/java/com/hotupdater → app/build/generated/source/codegen/java/com/facebook/fbreact/specs}/NativeHotUpdaterSpec.java +3 -2
  3. package/android/app/build/generated/source/codegen/jni/HotUpdater-generated.cpp +68 -0
  4. package/android/app/build/generated/source/codegen/jni/HotUpdater.h +31 -0
  5. package/android/{generated → app/build/generated/source/codegen}/jni/HotUpdaterSpec-generated.cpp +2 -2
  6. package/android/{generated/jni/react/renderer/components/HotUpdaterSpec/HotUpdaterSpecJSI-generated.cpp → app/build/generated/source/codegen/jni/react/renderer/components/HotUpdater/HotUpdaterJSI-generated.cpp} +3 -4
  7. package/{ios/generated/HotUpdaterSpecJSI.h → android/app/build/generated/source/codegen/jni/react/renderer/components/HotUpdater/HotUpdaterJSI.h} +53 -6
  8. package/{ios/generated → android/app/build/generated/source/codegen/jni/react/renderer/components/HotUpdaterSpec}/HotUpdaterSpecJSI-generated.cpp +2 -3
  9. package/android/{generated → app/build/generated/source/codegen}/jni/react/renderer/components/HotUpdaterSpec/HotUpdaterSpecJSI.h +59 -8
  10. package/android/src/main/java/com/hotupdater/BundleFileStorageService.kt +200 -0
  11. package/android/src/main/java/com/hotupdater/FileManagerService.kt +104 -0
  12. package/android/src/main/java/com/hotupdater/HotUpdater.kt +62 -305
  13. package/android/src/main/java/com/hotupdater/HotUpdaterFactory.kt +49 -0
  14. package/android/src/main/java/com/hotupdater/HotUpdaterImpl.kt +176 -0
  15. package/android/src/main/java/com/hotupdater/HttpDownloadService.kt +98 -0
  16. package/android/src/main/java/com/hotupdater/VersionedPreferencesService.kt +69 -0
  17. package/android/src/main/java/com/hotupdater/ZipFileUnzipService.kt +52 -0
  18. package/android/src/newarch/HotUpdaterModule.kt +31 -34
  19. package/android/src/newarch/ReactIntegrationManager.kt +17 -3
  20. package/android/src/oldarch/HotUpdaterModule.kt +32 -34
  21. package/android/src/oldarch/HotUpdaterSpec.kt +2 -9
  22. package/android/src/oldarch/ReactIntegrationManager.kt +0 -2
  23. package/ios/HotUpdater/Internal/BundleFileStorageService.swift +593 -0
  24. package/ios/HotUpdater/Internal/FileManagerService.swift +97 -0
  25. package/ios/HotUpdater/Internal/HotUpdater-Bridging-Header.h +8 -0
  26. package/ios/HotUpdater/Internal/HotUpdater.mm +241 -0
  27. package/ios/HotUpdater/Internal/HotUpdaterFactory.swift +24 -0
  28. package/ios/HotUpdater/Internal/HotUpdaterImpl.swift +143 -0
  29. package/ios/HotUpdater/Internal/NotificationExtension.swift +6 -0
  30. package/ios/HotUpdater/Internal/SSZipArchiveUnzipService.swift +25 -0
  31. package/ios/HotUpdater/Internal/URLSessionDownloadService.swift +101 -0
  32. package/ios/HotUpdater/Internal/VersionedPreferencesService.swift +82 -0
  33. package/ios/HotUpdater/Package.resolved +15 -0
  34. package/ios/HotUpdater/Public/HotUpdater.h +29 -0
  35. package/lib/commonjs/checkForUpdate.js +70 -0
  36. package/lib/commonjs/checkForUpdate.js.map +1 -0
  37. package/lib/commonjs/error.js +14 -0
  38. package/lib/commonjs/error.js.map +1 -0
  39. package/lib/commonjs/fetchUpdateInfo.js +74 -0
  40. package/lib/commonjs/fetchUpdateInfo.js.map +1 -0
  41. package/lib/commonjs/hooks/useEventCallback.js +17 -0
  42. package/lib/commonjs/hooks/useEventCallback.js.map +1 -0
  43. package/lib/commonjs/index.js +234 -0
  44. package/lib/commonjs/index.js.map +1 -0
  45. package/lib/commonjs/native.js +132 -0
  46. package/lib/commonjs/native.js.map +1 -0
  47. package/lib/commonjs/package.json +1 -0
  48. package/lib/commonjs/runUpdateProcess.js +69 -0
  49. package/lib/commonjs/runUpdateProcess.js.map +1 -0
  50. package/lib/commonjs/specs/NativeHotUpdater.js +9 -0
  51. package/lib/commonjs/specs/NativeHotUpdater.js.map +1 -0
  52. package/lib/commonjs/store.js +48 -0
  53. package/lib/commonjs/store.js.map +1 -0
  54. package/lib/commonjs/wrap.js +98 -0
  55. package/lib/commonjs/wrap.js.map +1 -0
  56. package/lib/module/checkForUpdate.js +64 -0
  57. package/lib/module/checkForUpdate.js.map +1 -0
  58. package/lib/module/error.js +9 -0
  59. package/lib/module/error.js.map +1 -0
  60. package/lib/module/fetchUpdateInfo.js +69 -0
  61. package/lib/module/fetchUpdateInfo.js.map +1 -0
  62. package/lib/module/hooks/useEventCallback.js +13 -0
  63. package/lib/module/hooks/useEventCallback.js.map +1 -0
  64. package/lib/module/index.js +211 -0
  65. package/lib/module/index.js.map +1 -0
  66. package/lib/module/native.js +119 -0
  67. package/lib/module/native.js.map +1 -0
  68. package/lib/module/package.json +1 -0
  69. package/lib/module/runUpdateProcess.js +64 -0
  70. package/lib/module/runUpdateProcess.js.map +1 -0
  71. package/lib/module/specs/NativeHotUpdater.js +5 -0
  72. package/lib/module/specs/NativeHotUpdater.js.map +1 -0
  73. package/lib/module/store.js +42 -0
  74. package/lib/module/store.js.map +1 -0
  75. package/lib/module/wrap.js +94 -0
  76. package/lib/module/wrap.js.map +1 -0
  77. package/lib/typescript/commonjs/checkForUpdate.d.ts +22 -0
  78. package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -0
  79. package/{dist → lib/typescript/commonjs}/error.d.ts +1 -0
  80. package/lib/typescript/commonjs/error.d.ts.map +1 -0
  81. package/lib/typescript/commonjs/fetchUpdateInfo.d.ts +4 -0
  82. package/lib/typescript/commonjs/fetchUpdateInfo.d.ts.map +1 -0
  83. package/{dist → lib/typescript/commonjs}/hooks/useEventCallback.d.ts +1 -0
  84. package/lib/typescript/commonjs/hooks/useEventCallback.d.ts.map +1 -0
  85. package/{dist → lib/typescript/commonjs}/index.d.ts +38 -12
  86. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  87. package/lib/typescript/commonjs/native.d.ts +64 -0
  88. package/lib/typescript/commonjs/native.d.ts.map +1 -0
  89. package/lib/typescript/commonjs/package.json +1 -0
  90. package/{dist → lib/typescript/commonjs}/runUpdateProcess.d.ts +1 -0
  91. package/lib/typescript/commonjs/runUpdateProcess.d.ts.map +1 -0
  92. package/{dist → lib/typescript/commonjs}/specs/NativeHotUpdater.d.ts +8 -9
  93. package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts.map +1 -0
  94. package/{dist → lib/typescript/commonjs}/store.d.ts +1 -0
  95. package/lib/typescript/commonjs/store.d.ts.map +1 -0
  96. package/{dist → lib/typescript/commonjs}/wrap.d.ts +3 -2
  97. package/lib/typescript/commonjs/wrap.d.ts.map +1 -0
  98. package/lib/typescript/module/checkForUpdate.d.ts +22 -0
  99. package/lib/typescript/module/checkForUpdate.d.ts.map +1 -0
  100. package/lib/typescript/module/error.d.ts +4 -0
  101. package/lib/typescript/module/error.d.ts.map +1 -0
  102. package/lib/typescript/module/fetchUpdateInfo.d.ts +4 -0
  103. package/lib/typescript/module/fetchUpdateInfo.d.ts.map +1 -0
  104. package/lib/typescript/module/hooks/useEventCallback.d.ts +5 -0
  105. package/lib/typescript/module/hooks/useEventCallback.d.ts.map +1 -0
  106. package/lib/typescript/module/index.d.ts +202 -0
  107. package/lib/typescript/module/index.d.ts.map +1 -0
  108. package/lib/typescript/module/native.d.ts +64 -0
  109. package/lib/typescript/module/native.d.ts.map +1 -0
  110. package/lib/typescript/module/package.json +1 -0
  111. package/lib/typescript/module/runUpdateProcess.d.ts +49 -0
  112. package/lib/typescript/module/runUpdateProcess.d.ts.map +1 -0
  113. package/lib/typescript/module/specs/NativeHotUpdater.d.ts +19 -0
  114. package/lib/typescript/module/specs/NativeHotUpdater.d.ts.map +1 -0
  115. package/lib/typescript/module/store.d.ts +11 -0
  116. package/lib/typescript/module/store.d.ts.map +1 -0
  117. package/lib/typescript/module/wrap.d.ts +51 -0
  118. package/lib/typescript/module/wrap.d.ts.map +1 -0
  119. package/package.json +59 -30
  120. package/src/checkForUpdate.ts +59 -9
  121. package/src/fetchUpdateInfo.ts +40 -12
  122. package/src/index.ts +37 -11
  123. package/src/native.ts +87 -41
  124. package/src/runUpdateProcess.ts +2 -2
  125. package/src/specs/NativeHotUpdater.ts +8 -10
  126. package/src/wrap.tsx +9 -13
  127. package/android/src/main/java/com/hotupdater/HotUpdaterPrefs.kt +0 -42
  128. package/dist/checkForUpdate.d.ts +0 -12
  129. package/dist/fetchUpdateInfo.d.ts +0 -3
  130. package/dist/index.js +0 -341
  131. package/dist/index.mjs +0 -301
  132. package/dist/native.d.ts +0 -41
  133. package/ios/HotUpdater/HotUpdater.h +0 -15
  134. package/ios/HotUpdater/HotUpdater.mm +0 -468
  135. package/ios/HotUpdater/HotUpdater.modulemap +0 -6
  136. package/ios/HotUpdater/HotUpdaterPrefs.h +0 -9
  137. package/ios/HotUpdater/HotUpdaterPrefs.mm +0 -45
  138. package/ios/generated/HotUpdaterSpec/HotUpdaterSpec-generated.mm +0 -81
  139. package/ios/generated/HotUpdaterSpec/HotUpdaterSpec.h +0 -112
  140. package/react-native.config.js +0 -12
  141. package/src/global.d.ts +0 -3
  142. /package/android/{generated → app/build/generated/source/codegen}/jni/CMakeLists.txt +0 -0
  143. /package/android/{generated → app/build/generated/source/codegen}/jni/HotUpdaterSpec.h +0 -0
@@ -13,19 +13,15 @@ Pod::Spec.new do |s|
13
13
 
14
14
  s.platforms = { :ios => min_ios_version_supported }
15
15
  s.source = { :git => "https://github.com/gronxb/hot-updater.git", :tag => "#{s.version}" }
16
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
17
+ s.public_header_files = "ios/HotUpdater/Public/*.h"
18
+ s.private_header_files = "ios/HotUpdater/Internal/*.h"
19
+ s.exclude_files = "ios/HotUpdater/Package.swift", "ios/HotUpdater/Test/**/*.{swift,h,m,mm}"
16
20
 
17
21
  s.pod_target_xcconfig = {
18
- 'SWIFT_VERSION' => '5.0',
19
- 'DEFINES_MODULE' => 'YES'
22
+ "DEFINES_MODULE" => "YES",
23
+ "OTHER_SWIFT_FLAGS" => "-enable-experimental-feature AccessLevelOnImport"
20
24
  }
21
-
22
- s.module_map = 'ios/HotUpdater/HotUpdater.modulemap'
23
-
24
- s.source_files = "ios/**/*.{h,m,mm}"
25
- if ENV['RCT_NEW_ARCH_ENABLED'] != '1' then
26
- s.exclude_files = "ios/generated/**/*"
27
- end
28
-
29
25
  s.dependency "SSZipArchive", "~> 2.2.2"
30
26
 
31
27
  # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
@@ -36,7 +32,7 @@ Pod::Spec.new do |s|
36
32
  s.dependency "React-Core"
37
33
 
38
34
  # Don't install the dependencies when we run `pod install` in the old architecture.
39
- if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
35
+ if ENV["RCT_NEW_ARCH_ENABLED"] == "1" then
40
36
  s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
41
37
  s.pod_target_xcconfig = {
42
38
  "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
@@ -10,13 +10,14 @@
10
10
  * @nolint
11
11
  */
12
12
 
13
- package com.hotupdater;
13
+ package com.facebook.fbreact.specs;
14
14
 
15
15
  import com.facebook.proguard.annotations.DoNotStrip;
16
16
  import com.facebook.react.bridge.Promise;
17
17
  import com.facebook.react.bridge.ReactApplicationContext;
18
18
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
19
19
  import com.facebook.react.bridge.ReactMethod;
20
+ import com.facebook.react.bridge.ReadableMap;
20
21
  import com.facebook.react.common.build.ReactBuildConfig;
21
22
  import com.facebook.react.turbomodule.core.interfaces.TurboModule;
22
23
  import java.util.Arrays;
@@ -44,7 +45,7 @@ public abstract class NativeHotUpdaterSpec extends ReactContextBaseJavaModule im
44
45
 
45
46
  @ReactMethod
46
47
  @DoNotStrip
47
- public abstract void updateBundle(String bundleId, @Nullable String zipUrl, Promise promise);
48
+ public abstract void updateBundle(ReadableMap params, Promise promise);
48
49
 
49
50
  @ReactMethod
50
51
  @DoNotStrip
@@ -0,0 +1,68 @@
1
+
2
+ /**
3
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
4
+ *
5
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
6
+ * once the code is regenerated.
7
+ *
8
+ * @generated by codegen project: GenerateModuleJniCpp.js
9
+ */
10
+
11
+ #include "HotUpdater.h"
12
+
13
+ namespace facebook::react {
14
+
15
+ static facebook::jsi::Value __hostFunction_NativeHotUpdaterSpecJSI_reload(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
16
+ static jmethodID cachedMethodId = nullptr;
17
+ return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, VoidKind, "reload", "()V", args, count, cachedMethodId);
18
+ }
19
+
20
+ static facebook::jsi::Value __hostFunction_NativeHotUpdaterSpecJSI_updateBundle(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
21
+ static jmethodID cachedMethodId = nullptr;
22
+ return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "updateBundle", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
23
+ }
24
+
25
+ static facebook::jsi::Value __hostFunction_NativeHotUpdaterSpecJSI_getAppVersion(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
26
+ static jmethodID cachedMethodId = nullptr;
27
+ return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "getAppVersion", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
28
+ }
29
+
30
+ static facebook::jsi::Value __hostFunction_NativeHotUpdaterSpecJSI_setChannel(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
31
+ static jmethodID cachedMethodId = nullptr;
32
+ return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "setChannel", "(Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
33
+ }
34
+
35
+ static facebook::jsi::Value __hostFunction_NativeHotUpdaterSpecJSI_addListener(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
36
+ static jmethodID cachedMethodId = nullptr;
37
+ return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, VoidKind, "addListener", "(Ljava/lang/String;)V", args, count, cachedMethodId);
38
+ }
39
+
40
+ static facebook::jsi::Value __hostFunction_NativeHotUpdaterSpecJSI_removeListeners(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
41
+ static jmethodID cachedMethodId = nullptr;
42
+ return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, VoidKind, "removeListeners", "(D)V", args, count, cachedMethodId);
43
+ }
44
+
45
+ static facebook::jsi::Value __hostFunction_NativeHotUpdaterSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
46
+ static jmethodID cachedMethodId = nullptr;
47
+ return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, ObjectKind, "getConstants", "()Ljava/util/Map;", args, count, cachedMethodId);
48
+ }
49
+
50
+ NativeHotUpdaterSpecJSI::NativeHotUpdaterSpecJSI(const JavaTurboModule::InitParams &params)
51
+ : JavaTurboModule(params) {
52
+ methodMap_["reload"] = MethodMetadata {0, __hostFunction_NativeHotUpdaterSpecJSI_reload};
53
+ methodMap_["updateBundle"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterSpecJSI_updateBundle};
54
+ methodMap_["getAppVersion"] = MethodMetadata {0, __hostFunction_NativeHotUpdaterSpecJSI_getAppVersion};
55
+ methodMap_["setChannel"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterSpecJSI_setChannel};
56
+ methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterSpecJSI_addListener};
57
+ methodMap_["removeListeners"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterSpecJSI_removeListeners};
58
+ methodMap_["getConstants"] = MethodMetadata {0, __hostFunction_NativeHotUpdaterSpecJSI_getConstants};
59
+ }
60
+
61
+ std::shared_ptr<TurboModule> HotUpdater_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams &params) {
62
+ if (moduleName == "HotUpdater") {
63
+ return std::make_shared<NativeHotUpdaterSpecJSI>(params);
64
+ }
65
+ return nullptr;
66
+ }
67
+
68
+ } // namespace facebook::react
@@ -0,0 +1,31 @@
1
+
2
+ /**
3
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
4
+ *
5
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
6
+ * once the code is regenerated.
7
+ *
8
+ * @generated by codegen project: GenerateModuleJniH.js
9
+ */
10
+
11
+ #pragma once
12
+
13
+ #include <ReactCommon/JavaTurboModule.h>
14
+ #include <ReactCommon/TurboModule.h>
15
+ #include <jsi/jsi.h>
16
+
17
+ namespace facebook::react {
18
+
19
+ /**
20
+ * JNI C++ class for module 'NativeHotUpdater'
21
+ */
22
+ class JSI_EXPORT NativeHotUpdaterSpecJSI : public JavaTurboModule {
23
+ public:
24
+ NativeHotUpdaterSpecJSI(const JavaTurboModule::InitParams &params);
25
+ };
26
+
27
+
28
+ JSI_EXPORT
29
+ std::shared_ptr<TurboModule> HotUpdater_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams &params);
30
+
31
+ } // namespace facebook::react
@@ -19,7 +19,7 @@ static facebook::jsi::Value __hostFunction_NativeHotUpdaterSpecJSI_reload(facebo
19
19
 
20
20
  static facebook::jsi::Value __hostFunction_NativeHotUpdaterSpecJSI_updateBundle(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
21
21
  static jmethodID cachedMethodId = nullptr;
22
- return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "updateBundle", "(Ljava/lang/String;Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
22
+ return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "updateBundle", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
23
23
  }
24
24
 
25
25
  static facebook::jsi::Value __hostFunction_NativeHotUpdaterSpecJSI_getAppVersion(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
@@ -50,7 +50,7 @@ static facebook::jsi::Value __hostFunction_NativeHotUpdaterSpecJSI_getConstants(
50
50
  NativeHotUpdaterSpecJSI::NativeHotUpdaterSpecJSI(const JavaTurboModule::InitParams &params)
51
51
  : JavaTurboModule(params) {
52
52
  methodMap_["reload"] = MethodMetadata {0, __hostFunction_NativeHotUpdaterSpecJSI_reload};
53
- methodMap_["updateBundle"] = MethodMetadata {2, __hostFunction_NativeHotUpdaterSpecJSI_updateBundle};
53
+ methodMap_["updateBundle"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterSpecJSI_updateBundle};
54
54
  methodMap_["getAppVersion"] = MethodMetadata {0, __hostFunction_NativeHotUpdaterSpecJSI_getAppVersion};
55
55
  methodMap_["setChannel"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterSpecJSI_setChannel};
56
56
  methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterSpecJSI_addListener};
@@ -7,7 +7,7 @@
7
7
  * @generated by codegen project: GenerateModuleCpp.js
8
8
  */
9
9
 
10
- #include "HotUpdaterSpecJSI.h"
10
+ #include "HotUpdaterJSI.h"
11
11
 
12
12
  namespace facebook::react {
13
13
 
@@ -20,8 +20,7 @@ static jsi::Value __hostFunction_NativeHotUpdaterCxxSpecJSI_reload(jsi::Runtime
20
20
  static jsi::Value __hostFunction_NativeHotUpdaterCxxSpecJSI_updateBundle(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
21
21
  return static_cast<NativeHotUpdaterCxxSpecJSI *>(&turboModule)->updateBundle(
22
22
  rt,
23
- count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt),
24
- count <= 1 || args[1].isNull() || args[1].isUndefined() ? std::nullopt : std::make_optional(args[1].asString(rt))
23
+ count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt)
25
24
  );
26
25
  }
27
26
  static jsi::Value __hostFunction_NativeHotUpdaterCxxSpecJSI_getAppVersion(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
@@ -58,7 +57,7 @@ static jsi::Value __hostFunction_NativeHotUpdaterCxxSpecJSI_getConstants(jsi::Ru
58
57
  NativeHotUpdaterCxxSpecJSI::NativeHotUpdaterCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
59
58
  : TurboModule("HotUpdater", jsInvoker) {
60
59
  methodMap_["reload"] = MethodMetadata {0, __hostFunction_NativeHotUpdaterCxxSpecJSI_reload};
61
- methodMap_["updateBundle"] = MethodMetadata {2, __hostFunction_NativeHotUpdaterCxxSpecJSI_updateBundle};
60
+ methodMap_["updateBundle"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterCxxSpecJSI_updateBundle};
62
61
  methodMap_["getAppVersion"] = MethodMetadata {0, __hostFunction_NativeHotUpdaterCxxSpecJSI_getAppVersion};
63
62
  methodMap_["setChannel"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterCxxSpecJSI_setChannel};
64
63
  methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterCxxSpecJSI_addListener};
@@ -15,13 +15,60 @@
15
15
  namespace facebook::react {
16
16
 
17
17
 
18
- class JSI_EXPORT NativeHotUpdaterCxxSpecJSI : public TurboModule {
18
+
19
+ #pragma mark - NativeHotUpdaterUpdateBundleParams
20
+
21
+ template <typename P0, typename P1>
22
+ struct NativeHotUpdaterUpdateBundleParams {
23
+ P0 bundleId;
24
+ P1 zipUrl;
25
+ bool operator==(const NativeHotUpdaterUpdateBundleParams &other) const {
26
+ return bundleId == other.bundleId && zipUrl == other.zipUrl;
27
+ }
28
+ };
29
+
30
+ template <typename T>
31
+ struct NativeHotUpdaterUpdateBundleParamsBridging {
32
+ static T types;
33
+
34
+ static T fromJs(
35
+ jsi::Runtime &rt,
36
+ const jsi::Object &value,
37
+ const std::shared_ptr<CallInvoker> &jsInvoker) {
38
+ T result{
39
+ bridging::fromJs<decltype(types.bundleId)>(rt, value.getProperty(rt, "bundleId"), jsInvoker),
40
+ bridging::fromJs<decltype(types.zipUrl)>(rt, value.getProperty(rt, "zipUrl"), jsInvoker)};
41
+ return result;
42
+ }
43
+
44
+ #ifdef DEBUG
45
+ static jsi::String bundleIdToJs(jsi::Runtime &rt, decltype(types.bundleId) value) {
46
+ return bridging::toJs(rt, value);
47
+ }
48
+
49
+ static std::optional<jsi::String> zipUrlToJs(jsi::Runtime &rt, decltype(types.zipUrl) value) {
50
+ return bridging::toJs(rt, value);
51
+ }
52
+ #endif
53
+
54
+ static jsi::Object toJs(
55
+ jsi::Runtime &rt,
56
+ const T &value,
57
+ const std::shared_ptr<CallInvoker> &jsInvoker) {
58
+ auto result = facebook::jsi::Object(rt);
59
+ result.setProperty(rt, "bundleId", bridging::toJs(rt, value.bundleId, jsInvoker));
60
+ result.setProperty(rt, "zipUrl", bridging::toJs(rt, value.zipUrl, jsInvoker));
61
+ return result;
62
+ }
63
+ };
64
+
65
+ class JSI_EXPORT NativeHotUpdaterCxxSpecJSI : public TurboModule {
19
66
  protected:
20
67
  NativeHotUpdaterCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
21
68
 
22
69
  public:
23
70
  virtual void reload(jsi::Runtime &rt) = 0;
24
- virtual jsi::Value updateBundle(jsi::Runtime &rt, jsi::String bundleId, std::optional<jsi::String> zipUrl) = 0;
71
+ virtual jsi::Value updateBundle(jsi::Runtime &rt, jsi::Object params) = 0;
25
72
  virtual jsi::Value getAppVersion(jsi::Runtime &rt) = 0;
26
73
  virtual jsi::Value setChannel(jsi::Runtime &rt, jsi::String channel) = 0;
27
74
  virtual void addListener(jsi::Runtime &rt, jsi::String eventName) = 0;
@@ -61,13 +108,13 @@ private:
61
108
  return bridging::callFromJs<void>(
62
109
  rt, &T::reload, jsInvoker_, instance_);
63
110
  }
64
- jsi::Value updateBundle(jsi::Runtime &rt, jsi::String bundleId, std::optional<jsi::String> zipUrl) override {
111
+ jsi::Value updateBundle(jsi::Runtime &rt, jsi::Object params) override {
65
112
  static_assert(
66
- bridging::getParameterCount(&T::updateBundle) == 3,
67
- "Expected updateBundle(...) to have 3 parameters");
113
+ bridging::getParameterCount(&T::updateBundle) == 2,
114
+ "Expected updateBundle(...) to have 2 parameters");
68
115
 
69
116
  return bridging::callFromJs<jsi::Value>(
70
- rt, &T::updateBundle, jsInvoker_, instance_, std::move(bundleId), std::move(zipUrl));
117
+ rt, &T::updateBundle, jsInvoker_, instance_, std::move(params));
71
118
  }
72
119
  jsi::Value getAppVersion(jsi::Runtime &rt) override {
73
120
  static_assert(
@@ -20,8 +20,7 @@ static jsi::Value __hostFunction_NativeHotUpdaterCxxSpecJSI_reload(jsi::Runtime
20
20
  static jsi::Value __hostFunction_NativeHotUpdaterCxxSpecJSI_updateBundle(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
21
21
  return static_cast<NativeHotUpdaterCxxSpecJSI *>(&turboModule)->updateBundle(
22
22
  rt,
23
- count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt),
24
- count <= 1 || args[1].isNull() || args[1].isUndefined() ? std::nullopt : std::make_optional(args[1].asString(rt))
23
+ count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt)
25
24
  );
26
25
  }
27
26
  static jsi::Value __hostFunction_NativeHotUpdaterCxxSpecJSI_getAppVersion(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
@@ -58,7 +57,7 @@ static jsi::Value __hostFunction_NativeHotUpdaterCxxSpecJSI_getConstants(jsi::Ru
58
57
  NativeHotUpdaterCxxSpecJSI::NativeHotUpdaterCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
59
58
  : TurboModule("HotUpdater", jsInvoker) {
60
59
  methodMap_["reload"] = MethodMetadata {0, __hostFunction_NativeHotUpdaterCxxSpecJSI_reload};
61
- methodMap_["updateBundle"] = MethodMetadata {2, __hostFunction_NativeHotUpdaterCxxSpecJSI_updateBundle};
60
+ methodMap_["updateBundle"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterCxxSpecJSI_updateBundle};
62
61
  methodMap_["getAppVersion"] = MethodMetadata {0, __hostFunction_NativeHotUpdaterCxxSpecJSI_getAppVersion};
63
62
  methodMap_["setChannel"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterCxxSpecJSI_setChannel};
64
63
  methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeHotUpdaterCxxSpecJSI_addListener};
@@ -15,13 +15,60 @@
15
15
  namespace facebook::react {
16
16
 
17
17
 
18
- class JSI_EXPORT NativeHotUpdaterCxxSpecJSI : public TurboModule {
18
+
19
+ #pragma mark - NativeHotUpdaterUpdateBundleParams
20
+
21
+ template <typename P0, typename P1>
22
+ struct NativeHotUpdaterUpdateBundleParams {
23
+ P0 bundleId;
24
+ P1 zipUrl;
25
+ bool operator==(const NativeHotUpdaterUpdateBundleParams &other) const {
26
+ return bundleId == other.bundleId && zipUrl == other.zipUrl;
27
+ }
28
+ };
29
+
30
+ template <typename T>
31
+ struct NativeHotUpdaterUpdateBundleParamsBridging {
32
+ static T types;
33
+
34
+ static T fromJs(
35
+ jsi::Runtime &rt,
36
+ const jsi::Object &value,
37
+ const std::shared_ptr<CallInvoker> &jsInvoker) {
38
+ T result{
39
+ bridging::fromJs<decltype(types.bundleId)>(rt, value.getProperty(rt, "bundleId"), jsInvoker),
40
+ bridging::fromJs<decltype(types.zipUrl)>(rt, value.getProperty(rt, "zipUrl"), jsInvoker)};
41
+ return result;
42
+ }
43
+
44
+ #ifdef DEBUG
45
+ static jsi::String bundleIdToJs(jsi::Runtime &rt, decltype(types.bundleId) value) {
46
+ return bridging::toJs(rt, value);
47
+ }
48
+
49
+ static std::optional<jsi::String> zipUrlToJs(jsi::Runtime &rt, decltype(types.zipUrl) value) {
50
+ return bridging::toJs(rt, value);
51
+ }
52
+ #endif
53
+
54
+ static jsi::Object toJs(
55
+ jsi::Runtime &rt,
56
+ const T &value,
57
+ const std::shared_ptr<CallInvoker> &jsInvoker) {
58
+ auto result = facebook::jsi::Object(rt);
59
+ result.setProperty(rt, "bundleId", bridging::toJs(rt, value.bundleId, jsInvoker));
60
+ result.setProperty(rt, "zipUrl", bridging::toJs(rt, value.zipUrl, jsInvoker));
61
+ return result;
62
+ }
63
+ };
64
+
65
+ class JSI_EXPORT NativeHotUpdaterCxxSpecJSI : public TurboModule {
19
66
  protected:
20
67
  NativeHotUpdaterCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
21
68
 
22
69
  public:
23
70
  virtual void reload(jsi::Runtime &rt) = 0;
24
- virtual jsi::Value updateBundle(jsi::Runtime &rt, jsi::String bundleId, std::optional<jsi::String> zipUrl) = 0;
71
+ virtual jsi::Value updateBundle(jsi::Runtime &rt, jsi::Object params) = 0;
25
72
  virtual jsi::Value getAppVersion(jsi::Runtime &rt) = 0;
26
73
  virtual jsi::Value setChannel(jsi::Runtime &rt, jsi::String channel) = 0;
27
74
  virtual void addListener(jsi::Runtime &rt, jsi::String eventName) = 0;
@@ -33,8 +80,12 @@ public:
33
80
  template <typename T>
34
81
  class JSI_EXPORT NativeHotUpdaterCxxSpec : public TurboModule {
35
82
  public:
36
- jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
37
- return delegate_.get(rt, propName);
83
+ jsi::Value create(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
84
+ return delegate_.create(rt, propName);
85
+ }
86
+
87
+ std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& runtime) override {
88
+ return delegate_.getPropertyNames(runtime);
38
89
  }
39
90
 
40
91
  static constexpr std::string_view kModuleName = "HotUpdater";
@@ -61,13 +112,13 @@ private:
61
112
  return bridging::callFromJs<void>(
62
113
  rt, &T::reload, jsInvoker_, instance_);
63
114
  }
64
- jsi::Value updateBundle(jsi::Runtime &rt, jsi::String bundleId, std::optional<jsi::String> zipUrl) override {
115
+ jsi::Value updateBundle(jsi::Runtime &rt, jsi::Object params) override {
65
116
  static_assert(
66
- bridging::getParameterCount(&T::updateBundle) == 3,
67
- "Expected updateBundle(...) to have 3 parameters");
117
+ bridging::getParameterCount(&T::updateBundle) == 2,
118
+ "Expected updateBundle(...) to have 2 parameters");
68
119
 
69
120
  return bridging::callFromJs<jsi::Value>(
70
- rt, &T::updateBundle, jsInvoker_, instance_, std::move(bundleId), std::move(zipUrl));
121
+ rt, &T::updateBundle, jsInvoker_, instance_, std::move(params));
71
122
  }
72
123
  jsi::Value getAppVersion(jsi::Runtime &rt) override {
73
124
  static_assert(
@@ -0,0 +1,200 @@
1
+ package com.hotupdater
2
+
3
+ import android.util.Log
4
+ import kotlinx.coroutines.Dispatchers
5
+ import kotlinx.coroutines.withContext
6
+ import java.io.File
7
+ import java.net.URL
8
+
9
+ /**
10
+ * Interface for bundle storage operations
11
+ */
12
+ interface BundleStorageService {
13
+ /**
14
+ * Sets the current bundle URL
15
+ * @param localPath Path to the bundle file (or null to reset)
16
+ * @return true if the operation was successful
17
+ */
18
+ fun setBundleURL(localPath: String?): Boolean
19
+
20
+ /**
21
+ * Gets the URL to the cached bundle file
22
+ * @return The path to the cached bundle or null if not found
23
+ */
24
+ fun getCachedBundleURL(): String?
25
+
26
+ /**
27
+ * Gets the URL to the fallback bundle included in the app
28
+ * @return The fallback bundle path
29
+ */
30
+ fun getFallbackBundleURL(): String
31
+
32
+ /**
33
+ * Gets the URL to the bundle file (cached or fallback)
34
+ * @return The path to the bundle file
35
+ */
36
+ fun getBundleURL(): String
37
+
38
+ /**
39
+ * Updates the bundle from the specified URL
40
+ * @param bundleId ID of the bundle to update
41
+ * @param fileUrl URL of the bundle file to download (or null to reset)
42
+ * @param progressCallback Callback for download progress updates
43
+ * @return true if the update was successful
44
+ */
45
+ suspend fun updateBundle(
46
+ bundleId: String,
47
+ fileUrl: String?,
48
+ progressCallback: (Double) -> Unit,
49
+ ): Boolean
50
+ }
51
+
52
+ /**
53
+ * Implementation of BundleStorageService
54
+ */
55
+ class BundleFileStorageService(
56
+ private val fileSystem: FileSystemService,
57
+ private val downloadService: DownloadService,
58
+ private val unzipService: UnzipService,
59
+ private val preferences: PreferencesService,
60
+ ) : BundleStorageService {
61
+ override fun setBundleURL(localPath: String?): Boolean {
62
+ preferences.setItem("HotUpdaterBundleURL", localPath)
63
+ return true
64
+ }
65
+
66
+ override fun getCachedBundleURL(): String? {
67
+ val urlString = preferences.getItem("HotUpdaterBundleURL")
68
+ if (urlString.isNullOrEmpty()) {
69
+ return null
70
+ }
71
+
72
+ val file = File(urlString)
73
+ if (!file.exists()) {
74
+ preferences.setItem("HotUpdaterBundleURL", null)
75
+ return null
76
+ }
77
+ return urlString
78
+ }
79
+
80
+ override fun getFallbackBundleURL(): String = "assets://index.android.bundle"
81
+
82
+ override fun getBundleURL(): String = getCachedBundleURL() ?: getFallbackBundleURL()
83
+
84
+ override suspend fun updateBundle(
85
+ bundleId: String,
86
+ fileUrl: String?,
87
+ progressCallback: (Double) -> Unit,
88
+ ): Boolean {
89
+ Log.d("BundleStorage", "updateBundle bundleId $bundleId fileUrl $fileUrl")
90
+
91
+ if (fileUrl.isNullOrEmpty()) {
92
+ setBundleURL(null)
93
+ return true
94
+ }
95
+
96
+ val baseDir = fileSystem.getExternalFilesDir()
97
+ val bundleStoreDir = File(baseDir, "bundle-store")
98
+ if (!bundleStoreDir.exists()) {
99
+ bundleStoreDir.mkdirs()
100
+ }
101
+
102
+ val finalBundleDir = File(bundleStoreDir, bundleId)
103
+ if (finalBundleDir.exists()) {
104
+ Log.d("BundleStorage", "Bundle for bundleId $bundleId already exists. Using cached bundle.")
105
+ val existingIndexFile = finalBundleDir.walk().find { it.name == "index.android.bundle" }
106
+ if (existingIndexFile != null) {
107
+ finalBundleDir.setLastModified(System.currentTimeMillis())
108
+ setBundleURL(existingIndexFile.absolutePath)
109
+ cleanupOldBundles(bundleStoreDir)
110
+ return true
111
+ } else {
112
+ finalBundleDir.deleteRecursively()
113
+ }
114
+ }
115
+
116
+ val tempDir = File(baseDir, "bundle-temp")
117
+ if (tempDir.exists()) {
118
+ tempDir.deleteRecursively()
119
+ }
120
+ tempDir.mkdirs()
121
+
122
+ val tempZipFile = File(tempDir, "bundle.zip")
123
+ val extractedDir = File(tempDir, "extracted")
124
+ extractedDir.mkdirs()
125
+
126
+ return withContext(Dispatchers.IO) {
127
+ val downloadUrl = URL(fileUrl)
128
+
129
+ // Download the file
130
+ val downloadResult =
131
+ downloadService.downloadFile(
132
+ downloadUrl,
133
+ tempZipFile,
134
+ progressCallback,
135
+ )
136
+
137
+ when (downloadResult) {
138
+ is DownloadResult.Error -> {
139
+ Log.d("BundleStorage", "Download failed: ${downloadResult.exception.message}")
140
+ tempDir.deleteRecursively()
141
+ return@withContext false
142
+ }
143
+ is DownloadResult.Success -> {
144
+ // Extract the zip file
145
+ if (!unzipService.extractZipFile(tempZipFile.absolutePath, extractedDir.absolutePath)) {
146
+ Log.d("BundleStorage", "Failed to extract zip file.")
147
+ tempDir.deleteRecursively()
148
+ return@withContext false
149
+ }
150
+
151
+ // Find the bundle file
152
+ val indexFileExtracted = extractedDir.walk().find { it.name == "index.android.bundle" }
153
+ if (indexFileExtracted == null) {
154
+ Log.d("BundleStorage", "index.android.bundle not found in extracted files.")
155
+ tempDir.deleteRecursively()
156
+ return@withContext false
157
+ }
158
+
159
+ // Move to final location
160
+ if (finalBundleDir.exists()) {
161
+ finalBundleDir.deleteRecursively()
162
+ }
163
+
164
+ if (!fileSystem.moveItem(extractedDir.absolutePath, finalBundleDir.absolutePath)) {
165
+ fileSystem.copyItem(extractedDir.absolutePath, finalBundleDir.absolutePath)
166
+ extractedDir.deleteRecursively()
167
+ }
168
+
169
+ val finalIndexFile = finalBundleDir.walk().find { it.name == "index.android.bundle" }
170
+ if (finalIndexFile == null) {
171
+ Log.d("BundleStorage", "index.android.bundle not found in final directory.")
172
+ tempDir.deleteRecursively()
173
+ return@withContext false
174
+ }
175
+
176
+ finalBundleDir.setLastModified(System.currentTimeMillis())
177
+ val bundlePath = finalIndexFile.absolutePath
178
+ Log.d("BundleStorage", "Setting bundle URL: $bundlePath")
179
+ setBundleURL(bundlePath)
180
+ cleanupOldBundles(bundleStoreDir)
181
+ tempDir.deleteRecursively()
182
+
183
+ Log.d("BundleStorage", "Downloaded and extracted file successfully.")
184
+ return@withContext true
185
+ }
186
+ }
187
+ }
188
+ }
189
+
190
+ private fun cleanupOldBundles(bundleStoreDir: File) {
191
+ val bundles = bundleStoreDir.listFiles { file -> file.isDirectory }?.toList() ?: return
192
+ val sortedBundles = bundles.sortedByDescending { it.lastModified() }
193
+ if (sortedBundles.size > 1) {
194
+ sortedBundles.drop(1).forEach { oldBundle ->
195
+ Log.d("BundleStorage", "Removing old bundle: ${oldBundle.name}")
196
+ oldBundle.deleteRecursively()
197
+ }
198
+ }
199
+ }
200
+ }