@hot-updater/react-native 1.0.0-rc.3 → 1.0.0-rc.30

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 (300) hide show
  1. package/android/proguard-rules.pro +17 -2
  2. package/android/src/main/java/com/hotupdater/BuiltInAssetResolver.kt +286 -0
  3. package/android/src/main/java/com/hotupdater/BundleFileStorageService.kt +954 -837
  4. package/android/src/main/java/com/hotupdater/BundleMetadata.kt +15 -11
  5. package/android/src/main/java/com/hotupdater/FileManagerService.kt +45 -0
  6. package/android/src/main/java/com/hotupdater/HotUpdaterException.kt +287 -22
  7. package/android/src/main/java/com/hotupdater/HotUpdaterImpl.kt +43 -31
  8. package/android/src/main/java/com/hotupdater/HotUpdaterRecoveryManager.kt +37 -54
  9. package/android/src/main/java/com/hotupdater/HotUpdaterRecoveryState.kt +64 -0
  10. package/android/src/main/java/com/hotupdater/InstallIdentityService.kt +37 -0
  11. package/android/src/main/java/com/hotupdater/KeyValueStorageService.kt +86 -0
  12. package/android/src/main/java/com/hotupdater/NetworkState.kt +31 -0
  13. package/android/src/main/java/com/hotupdater/NoBackupStorage.kt +17 -0
  14. package/android/src/main/java/com/hotupdater/OkHttpDownloadService.kt +127 -50
  15. package/android/src/main/java/com/hotupdater/PreviousProcessExit.kt +89 -0
  16. package/android/src/main/java/com/hotupdater/ReactNativeValueConverters.kt +34 -0
  17. package/android/src/main/java/com/hotupdater/TarArchiveInputStream.kt +214 -375
  18. package/android/src/main/java/com/hotupdater/TarBrArchiveExtractor.kt +119 -0
  19. package/android/src/newarch/HotUpdater.kt +7 -9
  20. package/android/src/newarch/HotUpdaterModule.kt +109 -84
  21. package/android/src/oldarch/HotUpdater.kt +7 -9
  22. package/android/src/oldarch/HotUpdaterModule.kt +98 -74
  23. package/android/src/oldarch/HotUpdaterSpec.kt +4 -6
  24. package/ios/HotUpdater/Internal/BrotliFileDecompressor.swift +167 -0
  25. package/ios/HotUpdater/Internal/BuiltInAssetResolver.swift +196 -0
  26. package/ios/HotUpdater/Internal/BundleFileStorageService.swift +950 -1112
  27. package/ios/HotUpdater/Internal/BundleMetadata.swift +8 -53
  28. package/ios/HotUpdater/Internal/FileManagerService.swift +48 -0
  29. package/ios/HotUpdater/Internal/FileUtilities.swift +64 -0
  30. package/ios/HotUpdater/Internal/HotUpdater-Bridging-Header.h +0 -1
  31. package/ios/HotUpdater/Internal/HotUpdater.mm +13 -45
  32. package/ios/HotUpdater/Internal/HotUpdaterImpl.swift +190 -73
  33. package/ios/HotUpdater/Internal/KeyValueStorageService.swift +71 -0
  34. package/ios/HotUpdater/Internal/NotificationExtension.swift +0 -2
  35. package/ios/HotUpdater/Internal/TarArchiveExtractor.swift +182 -311
  36. package/ios/HotUpdater/Internal/URLSessionDownloadService.swift +119 -71
  37. package/ios/HotUpdater/Internal/UpdateFailure.swift +390 -0
  38. package/ios/HotUpdater/Recovery/HotUpdaterRecovery.h +16 -0
  39. package/ios/HotUpdater/Recovery/HotUpdaterRecovery.mm +83 -0
  40. package/ios/HotUpdater/Recovery/HotUpdaterRecoveryHooks.mm +49 -0
  41. package/lib/commonjs/appReady.js +111 -0
  42. package/lib/commonjs/appReady.js.map +1 -0
  43. package/lib/commonjs/checkForUpdate.js +124 -69
  44. package/lib/commonjs/checkForUpdate.js.map +1 -1
  45. package/lib/commonjs/clientPlugin.js +13 -0
  46. package/lib/commonjs/clientPlugin.js.map +1 -0
  47. package/lib/commonjs/error.js +4 -13
  48. package/lib/commonjs/error.js.map +1 -1
  49. package/lib/commonjs/fetchJSON.js +16 -27
  50. package/lib/commonjs/fetchJSON.js.map +1 -1
  51. package/lib/commonjs/fetchUpdateResponse.js +54 -0
  52. package/lib/commonjs/fetchUpdateResponse.js.map +1 -0
  53. package/lib/commonjs/httpClient.js +63 -94
  54. package/lib/commonjs/httpClient.js.map +1 -1
  55. package/lib/commonjs/index.js +71 -18
  56. package/lib/commonjs/index.js.map +1 -1
  57. package/lib/commonjs/native.js +78 -60
  58. package/lib/commonjs/native.js.map +1 -1
  59. package/lib/commonjs/pluginHost.js +44 -0
  60. package/lib/commonjs/pluginHost.js.map +1 -0
  61. package/lib/commonjs/releaseCatalogCache.js +36 -87
  62. package/lib/commonjs/releaseCatalogCache.js.map +1 -1
  63. package/lib/commonjs/sdkVersion.js +1 -1
  64. package/lib/commonjs/sdkVersion.js.map +1 -1
  65. package/lib/commonjs/specs/NativeHotUpdater.js.map +1 -1
  66. package/lib/commonjs/store.js +3 -10
  67. package/lib/commonjs/store.js.map +1 -1
  68. package/lib/commonjs/updateError.js +132 -0
  69. package/lib/commonjs/updateError.js.map +1 -0
  70. package/lib/commonjs/wrap.js +43 -26
  71. package/lib/commonjs/wrap.js.map +1 -1
  72. package/lib/module/appReady.js +103 -0
  73. package/lib/module/appReady.js.map +1 -0
  74. package/lib/module/checkForUpdate.js +117 -64
  75. package/lib/module/checkForUpdate.js.map +1 -1
  76. package/lib/module/clientPlugin.js +4 -0
  77. package/lib/module/clientPlugin.js.map +1 -0
  78. package/lib/module/error.js +4 -13
  79. package/lib/module/error.js.map +1 -1
  80. package/lib/module/fetchJSON.js +14 -26
  81. package/lib/module/fetchJSON.js.map +1 -1
  82. package/lib/module/fetchUpdateResponse.js +49 -0
  83. package/lib/module/fetchUpdateResponse.js.map +1 -0
  84. package/lib/module/httpClient.js +62 -93
  85. package/lib/module/httpClient.js.map +1 -1
  86. package/lib/module/index.js +58 -20
  87. package/lib/module/index.js.map +1 -1
  88. package/lib/module/native.js +71 -53
  89. package/lib/module/native.js.map +1 -1
  90. package/lib/module/pluginHost.js +35 -0
  91. package/lib/module/pluginHost.js.map +1 -0
  92. package/lib/module/releaseCatalogCache.js +32 -82
  93. package/lib/module/releaseCatalogCache.js.map +1 -1
  94. package/lib/module/sdkVersion.js +1 -1
  95. package/lib/module/sdkVersion.js.map +1 -1
  96. package/lib/module/specs/NativeHotUpdater.js.map +1 -1
  97. package/lib/module/store.js +3 -10
  98. package/lib/module/store.js.map +1 -1
  99. package/lib/module/updateError.js +126 -0
  100. package/lib/module/updateError.js.map +1 -0
  101. package/lib/module/wrap.js +43 -26
  102. package/lib/module/wrap.js.map +1 -1
  103. package/lib/typescript/commonjs/appReady.d.ts +23 -0
  104. package/lib/typescript/commonjs/appReady.d.ts.map +1 -0
  105. package/lib/typescript/commonjs/checkForUpdate.d.ts +16 -4
  106. package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
  107. package/lib/typescript/commonjs/clientPlugin.d.ts +2 -0
  108. package/lib/typescript/commonjs/clientPlugin.d.ts.map +1 -0
  109. package/lib/typescript/commonjs/error.d.ts +4 -13
  110. package/lib/typescript/commonjs/error.d.ts.map +1 -1
  111. package/lib/typescript/commonjs/fetchJSON.d.ts +5 -5
  112. package/lib/typescript/commonjs/fetchJSON.d.ts.map +1 -1
  113. package/lib/typescript/commonjs/fetchUpdateResponse.d.ts +14 -0
  114. package/lib/typescript/commonjs/fetchUpdateResponse.d.ts.map +1 -0
  115. package/lib/typescript/commonjs/httpClient.d.ts +4 -33
  116. package/lib/typescript/commonjs/httpClient.d.ts.map +1 -1
  117. package/lib/typescript/commonjs/index.d.ts +4 -8
  118. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  119. package/lib/typescript/commonjs/native.d.ts +31 -22
  120. package/lib/typescript/commonjs/native.d.ts.map +1 -1
  121. package/lib/typescript/commonjs/pluginHost.d.ts +4 -0
  122. package/lib/typescript/commonjs/pluginHost.d.ts.map +1 -0
  123. package/lib/typescript/commonjs/releaseCatalogCache.d.ts +8 -14
  124. package/lib/typescript/commonjs/releaseCatalogCache.d.ts.map +1 -1
  125. package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
  126. package/lib/typescript/commonjs/sdkVersion.d.ts.map +1 -1
  127. package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts +42 -47
  128. package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts.map +1 -1
  129. package/lib/typescript/commonjs/store.d.ts +1 -3
  130. package/lib/typescript/commonjs/store.d.ts.map +1 -1
  131. package/lib/typescript/commonjs/types.d.ts +1 -1
  132. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  133. package/lib/typescript/commonjs/updateError.d.ts +26 -0
  134. package/lib/typescript/commonjs/updateError.d.ts.map +1 -0
  135. package/lib/typescript/commonjs/wrap.d.ts.map +1 -1
  136. package/lib/typescript/commonjs/wrap.types.d.ts +6 -7
  137. package/lib/typescript/commonjs/wrap.types.d.ts.map +1 -1
  138. package/lib/typescript/module/appReady.d.ts +23 -0
  139. package/lib/typescript/module/appReady.d.ts.map +1 -0
  140. package/lib/typescript/module/checkForUpdate.d.ts +16 -4
  141. package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
  142. package/lib/typescript/module/clientPlugin.d.ts +2 -0
  143. package/lib/typescript/module/clientPlugin.d.ts.map +1 -0
  144. package/lib/typescript/module/error.d.ts +4 -13
  145. package/lib/typescript/module/error.d.ts.map +1 -1
  146. package/lib/typescript/module/fetchJSON.d.ts +5 -5
  147. package/lib/typescript/module/fetchJSON.d.ts.map +1 -1
  148. package/lib/typescript/module/fetchUpdateResponse.d.ts +14 -0
  149. package/lib/typescript/module/fetchUpdateResponse.d.ts.map +1 -0
  150. package/lib/typescript/module/httpClient.d.ts +4 -33
  151. package/lib/typescript/module/httpClient.d.ts.map +1 -1
  152. package/lib/typescript/module/index.d.ts +4 -8
  153. package/lib/typescript/module/index.d.ts.map +1 -1
  154. package/lib/typescript/module/native.d.ts +31 -22
  155. package/lib/typescript/module/native.d.ts.map +1 -1
  156. package/lib/typescript/module/pluginHost.d.ts +4 -0
  157. package/lib/typescript/module/pluginHost.d.ts.map +1 -0
  158. package/lib/typescript/module/releaseCatalogCache.d.ts +8 -14
  159. package/lib/typescript/module/releaseCatalogCache.d.ts.map +1 -1
  160. package/lib/typescript/module/sdkVersion.d.ts +1 -1
  161. package/lib/typescript/module/sdkVersion.d.ts.map +1 -1
  162. package/lib/typescript/module/specs/NativeHotUpdater.d.ts +42 -47
  163. package/lib/typescript/module/specs/NativeHotUpdater.d.ts.map +1 -1
  164. package/lib/typescript/module/store.d.ts +1 -3
  165. package/lib/typescript/module/store.d.ts.map +1 -1
  166. package/lib/typescript/module/types.d.ts +1 -1
  167. package/lib/typescript/module/types.d.ts.map +1 -1
  168. package/lib/typescript/module/updateError.d.ts +26 -0
  169. package/lib/typescript/module/updateError.d.ts.map +1 -0
  170. package/lib/typescript/module/wrap.d.ts.map +1 -1
  171. package/lib/typescript/module/wrap.types.d.ts +6 -7
  172. package/lib/typescript/module/wrap.types.d.ts.map +1 -1
  173. package/package.json +7 -4
  174. package/src/appReady.ts +149 -0
  175. package/src/checkForUpdate.ts +151 -88
  176. package/src/clientPlugin.ts +18 -0
  177. package/src/error.ts +4 -14
  178. package/src/fetchJSON.ts +14 -30
  179. package/src/fetchUpdateResponse.ts +54 -0
  180. package/src/httpClient.ts +88 -159
  181. package/src/index.ts +90 -24
  182. package/src/native.ts +106 -102
  183. package/src/pluginHost.ts +45 -0
  184. package/src/releaseCatalogCache.ts +43 -172
  185. package/src/sdkVersion.ts +1 -1
  186. package/src/specs/NativeHotUpdater.ts +41 -48
  187. package/src/store.ts +2 -23
  188. package/src/types.ts +1 -1
  189. package/src/updateError.ts +153 -0
  190. package/src/wrap.tsx +57 -26
  191. package/src/wrap.types.ts +6 -7
  192. package/android/src/main/java/com/hotupdater/DecompressService.kt +0 -89
  193. package/android/src/main/java/com/hotupdater/DecompressionStrategy.kt +0 -26
  194. package/android/src/main/java/com/hotupdater/TarBrDecompressionStrategy.kt +0 -117
  195. package/android/src/main/java/com/hotupdater/TarGzDecompressionStrategy.kt +0 -117
  196. package/android/src/main/java/com/hotupdater/ZipDecompressionStrategy.kt +0 -192
  197. package/android/src/test/java/com/hotupdater/BsdiffPatchTest.kt +0 -46
  198. package/android/src/test/java/com/hotupdater/BundleFileStorageServiceTest.kt +0 -799
  199. package/android/src/test/java/com/hotupdater/HotUpdaterImplTest.kt +0 -273
  200. package/android/src/test/java/com/hotupdater/NativeConfigUtilsTest.kt +0 -20
  201. package/android/src/test/java/com/hotupdater/OkHttpDownloadServiceTest.kt +0 -111
  202. package/android/src/test/java/com/hotupdater/RelativePathResolverTest.kt +0 -41
  203. package/android/src/test/java/com/hotupdater/ReleaseCatalogCacheServiceTest.kt +0 -118
  204. package/android/src/test/java/com/hotupdater/TarArchiveInputStreamTest.kt +0 -68
  205. package/ios/HotUpdater/Internal/ArchiveExtractionUtilities.swift +0 -178
  206. package/ios/HotUpdater/Internal/DecompressService.swift +0 -112
  207. package/ios/HotUpdater/Internal/DecompressionStrategy.swift +0 -22
  208. package/ios/HotUpdater/Internal/StreamingTarArchiveExtractor.swift +0 -370
  209. package/ios/HotUpdater/Internal/TarBrDecompressionStrategy.swift +0 -39
  210. package/ios/HotUpdater/Internal/TarGzDecompressionStrategy.swift +0 -59
  211. package/ios/HotUpdater/Internal/ZipArchiveExtractor.swift +0 -482
  212. package/ios/HotUpdater/Internal/ZipDecompressionStrategy.swift +0 -56
  213. package/lib/commonjs/catalogCacheNative.spec.js +0 -31
  214. package/lib/commonjs/catalogCacheNative.spec.js.map +0 -1
  215. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js +0 -615
  216. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js.map +0 -1
  217. package/lib/commonjs/httpClient.spec.js +0 -102
  218. package/lib/commonjs/httpClient.spec.js.map +0 -1
  219. package/lib/commonjs/index.spec.js +0 -302
  220. package/lib/commonjs/index.spec.js.map +0 -1
  221. package/lib/commonjs/iosInterop.spec.js +0 -18
  222. package/lib/commonjs/iosInterop.spec.js.map +0 -1
  223. package/lib/commonjs/native.spec.js +0 -883
  224. package/lib/commonjs/native.spec.js.map +0 -1
  225. package/lib/commonjs/notifyAppReadyInsights.boundary.spec.js +0 -218
  226. package/lib/commonjs/notifyAppReadyInsights.boundary.spec.js.map +0 -1
  227. package/lib/commonjs/notifyAppReadyInsights.js +0 -133
  228. package/lib/commonjs/notifyAppReadyInsights.js.map +0 -1
  229. package/lib/commonjs/notifyAppReadyInsights.spec.js +0 -246
  230. package/lib/commonjs/notifyAppReadyInsights.spec.js.map +0 -1
  231. package/lib/commonjs/notifyAppReadyInsights.test-utils.js +0 -24
  232. package/lib/commonjs/notifyAppReadyInsights.test-utils.js.map +0 -1
  233. package/lib/commonjs/notifyAppReadyInsights.transport.spec.js +0 -117
  234. package/lib/commonjs/notifyAppReadyInsights.transport.spec.js.map +0 -1
  235. package/lib/commonjs/releaseCatalogCache.spec.js +0 -195
  236. package/lib/commonjs/releaseCatalogCache.spec.js.map +0 -1
  237. package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js +0 -64
  238. package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js.map +0 -1
  239. package/lib/commonjs/store.notification.spec.js +0 -76
  240. package/lib/commonjs/store.notification.spec.js.map +0 -1
  241. package/lib/commonjs/store.spec.js +0 -316
  242. package/lib/commonjs/store.spec.js.map +0 -1
  243. package/lib/commonjs/wrap.spec.js +0 -329
  244. package/lib/commonjs/wrap.spec.js.map +0 -1
  245. package/lib/module/catalogCacheNative.spec.js +0 -31
  246. package/lib/module/catalogCacheNative.spec.js.map +0 -1
  247. package/lib/module/checkForUpdate.releaseCatalog.spec.js +0 -614
  248. package/lib/module/checkForUpdate.releaseCatalog.spec.js.map +0 -1
  249. package/lib/module/httpClient.spec.js +0 -102
  250. package/lib/module/httpClient.spec.js.map +0 -1
  251. package/lib/module/index.spec.js +0 -301
  252. package/lib/module/index.spec.js.map +0 -1
  253. package/lib/module/iosInterop.spec.js +0 -18
  254. package/lib/module/iosInterop.spec.js.map +0 -1
  255. package/lib/module/native.spec.js +0 -882
  256. package/lib/module/native.spec.js.map +0 -1
  257. package/lib/module/notifyAppReadyInsights.boundary.spec.js +0 -217
  258. package/lib/module/notifyAppReadyInsights.boundary.spec.js.map +0 -1
  259. package/lib/module/notifyAppReadyInsights.js +0 -128
  260. package/lib/module/notifyAppReadyInsights.js.map +0 -1
  261. package/lib/module/notifyAppReadyInsights.spec.js +0 -245
  262. package/lib/module/notifyAppReadyInsights.spec.js.map +0 -1
  263. package/lib/module/notifyAppReadyInsights.test-utils.js +0 -18
  264. package/lib/module/notifyAppReadyInsights.test-utils.js.map +0 -1
  265. package/lib/module/notifyAppReadyInsights.transport.spec.js +0 -116
  266. package/lib/module/notifyAppReadyInsights.transport.spec.js.map +0 -1
  267. package/lib/module/releaseCatalogCache.spec.js +0 -195
  268. package/lib/module/releaseCatalogCache.spec.js.map +0 -1
  269. package/lib/module/releaseCatalogCacheNativeContract.spec.js +0 -64
  270. package/lib/module/releaseCatalogCacheNativeContract.spec.js.map +0 -1
  271. package/lib/module/store.notification.spec.js +0 -77
  272. package/lib/module/store.notification.spec.js.map +0 -1
  273. package/lib/module/store.spec.js +0 -315
  274. package/lib/module/store.spec.js.map +0 -1
  275. package/lib/module/wrap.spec.js +0 -330
  276. package/lib/module/wrap.spec.js.map +0 -1
  277. package/lib/typescript/commonjs/notifyAppReadyInsights.d.ts +0 -13
  278. package/lib/typescript/commonjs/notifyAppReadyInsights.d.ts.map +0 -1
  279. package/lib/typescript/commonjs/notifyAppReadyInsights.test-utils.d.ts +0 -8
  280. package/lib/typescript/commonjs/notifyAppReadyInsights.test-utils.d.ts.map +0 -1
  281. package/lib/typescript/module/notifyAppReadyInsights.d.ts +0 -13
  282. package/lib/typescript/module/notifyAppReadyInsights.d.ts.map +0 -1
  283. package/lib/typescript/module/notifyAppReadyInsights.test-utils.d.ts +0 -8
  284. package/lib/typescript/module/notifyAppReadyInsights.test-utils.d.ts.map +0 -1
  285. package/src/catalogCacheNative.spec.ts +0 -63
  286. package/src/checkForUpdate.releaseCatalog.spec.ts +0 -611
  287. package/src/httpClient.spec.ts +0 -132
  288. package/src/index.spec.ts +0 -337
  289. package/src/iosInterop.spec.ts +0 -30
  290. package/src/native.spec.ts +0 -945
  291. package/src/notifyAppReadyInsights.boundary.spec.ts +0 -234
  292. package/src/notifyAppReadyInsights.spec.ts +0 -243
  293. package/src/notifyAppReadyInsights.test-utils.ts +0 -31
  294. package/src/notifyAppReadyInsights.transport.spec.ts +0 -130
  295. package/src/notifyAppReadyInsights.ts +0 -194
  296. package/src/releaseCatalogCache.spec.ts +0 -282
  297. package/src/releaseCatalogCacheNativeContract.spec.ts +0 -80
  298. package/src/store.notification.spec.ts +0 -92
  299. package/src/store.spec.ts +0 -372
  300. package/src/wrap.spec.ts +0 -406
@@ -2,48 +2,21 @@ import type { TurboModule } from "react-native";
2
2
  import { TurboModuleRegistry } from "react-native";
3
3
  import type { UnsafeObject } from "react-native/Libraries/Types/CodegenTypes";
4
4
 
5
- export interface ChangedAsset {
6
- file?: {
7
- compression?: "br" | null;
8
- url: string;
9
- } | null;
10
- fileHash: string;
11
- patch?: {
12
- algorithm: "bsdiff";
13
- baseBundleId: string;
14
- baseFileHash: string;
15
- patchFileHash: string;
16
- patchUrl: string;
17
- } | null;
18
- }
19
-
20
5
  export interface UpdateBundleParams {
21
6
  bundleId: string;
22
7
  channel?: string;
23
- fileUrl: string | null;
24
8
  /**
25
- * File hash for integrity/signature verification.
26
- *
27
- * Format depends on signing configuration:
28
- * - Signed: `sig:<base64_signature>` - Native will verify signature (and implicitly hash)
29
- * - Unsigned: `<hex_hash>` - Native will verify SHA256 hash only
30
- *
31
- * Native determines verification mode by checking for "sig:" prefix.
9
+ * Signed manifest URL for installation.
32
10
  */
33
- fileHash: string | null;
34
- /**
35
- * Optional signed manifest URL for manifest-driven installation.
36
- */
37
- manifestUrl?: string | null;
11
+ manifestUrl: string;
38
12
  /**
39
13
  * File hash/signature for the manifest file itself.
40
14
  */
41
- manifestFileHash?: string | null;
42
- /**
43
- * Per-file URLs for assets that must be downloaded instead of reused from
44
- * the currently active bundle.
45
- */
46
- changedAssets?: UnsafeObject | null;
15
+ manifestFileHash: string;
16
+ /** Optional tar.br URL; integrity and sizes come from the verified manifest. */
17
+ archiveUrl?: string | null;
18
+ /** Full protocol v1 target file descriptor map. */
19
+ assets: UnsafeObject;
47
20
  /** Full Release Catalog selection receipt committed with the staged Bundle. */
48
21
  selection?: UnsafeObject | null;
49
22
  }
@@ -61,18 +34,21 @@ export interface Spec extends TurboModule {
61
34
  * Downloads and applies a bundle update.
62
35
  *
63
36
  * @param params - Update bundle parameters
64
- * @returns Promise that resolves to true if successful
37
+ * @returns Promise that resolves, once the bundle is staged, to how it
38
+ * arrived: `{ delivery, patchFallback }`. `delivery` is "patch" when a
39
+ * bsdiff patch produced a file, "manifest" when only changed files were
40
+ * downloaded, or "archive" for the full archive; `patchFallback` is true
41
+ * when a patch was tried but the file or archive was downloaded instead.
65
42
  * @throws {HotUpdaterErrorCode} Rejects with one of the following error codes:
66
43
  *
67
44
  * Parameter validation:
68
45
  * - MISSING_BUNDLE_ID: Missing or empty bundleId
69
- * - INVALID_FILE_URL: Invalid fileUrl provided
46
+ * - INVALID_FILE_URL: Invalid manifest or asset URL provided
70
47
  *
71
48
  * Bundle storage:
72
49
  * - DIRECTORY_CREATION_FAILED: Failed to create bundle directory
73
50
  * - DOWNLOAD_FAILED: Failed to download bundle
74
51
  * - INCOMPLETE_DOWNLOAD: Download incomplete (size mismatch)
75
- * - EXTRACTION_FORMAT_ERROR: Invalid or corrupted archive format
76
52
  * - INVALID_BUNDLE: Bundle missing required platform files
77
53
  * - INSUFFICIENT_DISK_SPACE: Insufficient disk space
78
54
  * - MOVE_OPERATION_FAILED: Failed to move bundle files
@@ -87,8 +63,20 @@ export interface Spec extends TurboModule {
87
63
  *
88
64
  * Note: iOS normalizes rare signature/storage errors to SIGNATURE_VERIFICATION_FAILED
89
65
  * or UNKNOWN_ERROR to keep the JS error surface small.
66
+ *
67
+ * A rejection from the download or install also carries `userInfo`
68
+ * `{ stage, reason, resource?, httpStatus?, transport?, originCode? }`:
69
+ * `stage` is "download" (transfer and verification) or "install" (patch,
70
+ * extract, move into place); `reason` is one of "network", "http",
71
+ * "invalid_response", "hash_mismatch", "signature", "patch", "extract",
72
+ * "storage", or "unknown"; `resource` is what was being fetched or
73
+ * applied: "manifest", "file", "patch", or "archive". `httpStatus` is
74
+ * present when `reason` is "http", with `originCode`, the storage
75
+ * origin's XML error `<Code>` when the body names one. `transport` is
76
+ * present when no response arrived: "timeout", "dns", "tls",
77
+ * "connection", "offline", or "cancelled".
90
78
  */
91
- updateBundle(params: UpdateBundleParams): Promise<boolean>;
79
+ updateBundle(params: UpdateBundleParams): Promise<UnsafeObject>;
92
80
 
93
81
  /** Accepts and durably advances the catalog high-water for a scope. */
94
82
  acceptReleaseCatalog(params: UnsafeObject): boolean;
@@ -126,6 +114,13 @@ export interface Spec extends TurboModule {
126
114
  toBundleId?: string;
127
115
  updateStrategy?: "fingerprint" | "appVersion";
128
116
  crashedBundleId?: string;
117
+ /**
118
+ * Android 11+: why the app's previous main process exited, the
119
+ * `ApplicationExitInfo` reason without its `REASON_` prefix (for
120
+ * example "CRASH", "ANR", "LOW_MEMORY", "USER_REQUESTED"), read once
121
+ * when the process starts. Absent on iOS and older Android.
122
+ */
123
+ previousProcessExit?: string;
129
124
  };
130
125
 
131
126
  /**
@@ -192,24 +187,22 @@ export interface Spec extends TurboModule {
192
187
  getCohort: () => string;
193
188
 
194
189
  /**
195
- * Gets the persisted install id for this app installation.
190
+ * Gets the install id: a random id native creates once per app
191
+ * installation and keeps out of device backups.
196
192
  */
197
193
  getInstallId: () => string;
198
194
 
199
195
  /**
200
- * Gets the persisted nullable user id associated with this installation.
201
- */
202
- getUserId: () => string | null;
203
-
204
- /**
205
- * Gets the persisted nullable username associated with this installation.
196
+ * Reads a value from the SDK's persistent key-value store, which native
197
+ * keeps out of device backups. Returns null when the key has no value.
206
198
  */
207
- getUsername: () => string | null;
199
+ getStorageItem: (key: string) => string | null;
208
200
 
209
201
  /**
210
- * Persists nullable user identity fields associated with this installation.
202
+ * Writes a value to the SDK's persistent key-value store; null removes the
203
+ * key.
211
204
  */
212
- setUser: (userId: string | null, username: string | null) => void;
205
+ setStorageItem: (key: string, value: string | null) => void;
213
206
 
214
207
  // EventEmitter
215
208
  addListener(eventName: string): void;
package/src/store.ts CHANGED
@@ -9,10 +9,8 @@ import { addListener } from "./native";
9
9
 
10
10
  export type HotUpdaterState = {
11
11
  progress: number;
12
- downloadedBytes: number | undefined;
13
- totalBytes: number | undefined;
14
12
  isUpdateDownloaded: boolean;
15
- artifactType: "archive" | "diff" | null;
13
+ artifactType: "diff" | null;
16
14
  details: HotUpdaterDiffProgressDetails | null;
17
15
  };
18
16
 
@@ -56,8 +54,6 @@ const areDiffDetailsEqual = (
56
54
  const areStatesEqual = (left: HotUpdaterState, right: HotUpdaterState) => {
57
55
  return (
58
56
  left.progress === right.progress &&
59
- left.downloadedBytes === right.downloadedBytes &&
60
- left.totalBytes === right.totalBytes &&
61
57
  left.isUpdateDownloaded === right.isUpdateDownloaded &&
62
58
  left.artifactType === right.artifactType &&
63
59
  areDiffDetailsEqual(left.details, right.details)
@@ -78,8 +74,6 @@ const normalizeDownloadPath = (value: string | undefined) => {
78
74
  const createHotUpdaterStore = () => {
79
75
  let state: HotUpdaterState = {
80
76
  progress: 0,
81
- downloadedBytes: undefined,
82
- totalBytes: undefined,
83
77
  isUpdateDownloaded: false,
84
78
  artifactType: null,
85
79
  details: null,
@@ -165,10 +159,6 @@ const createHotUpdaterStore = () => {
165
159
  nextState.details = state.details;
166
160
  }
167
161
 
168
- if (nextState.artifactType !== "diff") {
169
- nextState.details = null;
170
- }
171
-
172
162
  if (areStatesEqual(state, nextState)) {
173
163
  return;
174
164
  }
@@ -180,19 +170,8 @@ const createHotUpdaterStore = () => {
180
170
  const applyProgressEvent = (event: HotUpdaterProgressEvent) => {
181
171
  setState({
182
172
  artifactType: event.artifactType,
183
- details:
184
- event.artifactType === "diff"
185
- ? normalizeDiffDetails(event.details)
186
- : null,
187
- downloadedBytes:
188
- event.artifactType === "archive"
189
- ? normalizeByteCount(event.downloadedBytes)
190
- : undefined,
173
+ details: normalizeDiffDetails(event.details),
191
174
  progress: event.progress,
192
- totalBytes:
193
- event.artifactType === "archive"
194
- ? normalizeByteCount(event.totalBytes)
195
- : undefined,
196
175
  });
197
176
  };
198
177
 
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type HotUpdaterBaseURL = string | (() => string | Promise<string>);
1
+ export type { HotUpdaterBaseURL } from "@hot-updater/protocol";
2
2
 
3
3
  /**
4
4
  * Information about a signature verification failure.
@@ -0,0 +1,153 @@
1
+ import type {
2
+ UpdateError,
3
+ UpdateErrorReason,
4
+ UpdateErrorResource,
5
+ UpdateErrorStage,
6
+ UpdateErrorTransport,
7
+ } from "./clientPlugin";
8
+ import { HotUpdaterError } from "./error";
9
+
10
+ /**
11
+ * A response the SDK cannot use: a malformed or stale catalog, an artifact
12
+ * in another protocol, or an invalid URL.
13
+ */
14
+ export class InvalidUpdateResponseError extends HotUpdaterError {
15
+ constructor(message: string, options?: { cause?: unknown }) {
16
+ super(message);
17
+ this.name = "InvalidUpdateResponseError";
18
+ if (options?.cause !== undefined) this.cause = options.cause;
19
+ }
20
+ }
21
+
22
+ /** A request the server answered with a status the SDK does not accept. */
23
+ export class UpdateHttpError extends HotUpdaterError {
24
+ constructor(
25
+ readonly status: number,
26
+ statusText: string,
27
+ ) {
28
+ super(
29
+ `Request failed with HTTP ${status}${statusText ? ` ${statusText}` : ""}`,
30
+ );
31
+ this.name = "UpdateHttpError";
32
+ }
33
+ }
34
+
35
+ const STAGES: readonly UpdateErrorStage[] = ["check", "download", "install"];
36
+ const REASONS: readonly UpdateErrorReason[] = [
37
+ "network",
38
+ "http",
39
+ "invalid_response",
40
+ "hash_mismatch",
41
+ "signature",
42
+ "patch",
43
+ "extract",
44
+ "storage",
45
+ "unknown",
46
+ ];
47
+ const RESOURCES: readonly UpdateErrorResource[] = [
48
+ "catalog",
49
+ "artifact",
50
+ "manifest",
51
+ "file",
52
+ "patch",
53
+ "archive",
54
+ ];
55
+ const TRANSPORTS: readonly UpdateErrorTransport[] = [
56
+ "timeout",
57
+ "dns",
58
+ "tls",
59
+ "connection",
60
+ "offline",
61
+ "cancelled",
62
+ ];
63
+ /** An S3, R2, or GCS error code: letters, digits, and punctuation only. */
64
+ const ORIGIN_CODE = /^[A-Za-z0-9._-]{1,64}$/;
65
+
66
+ type Classification = Pick<
67
+ UpdateError,
68
+ "stage" | "reason" | "resource" | "httpStatus" | "originCode" | "transport"
69
+ >;
70
+
71
+ const oneOf = <T extends string>(
72
+ values: readonly T[],
73
+ value: unknown,
74
+ ): value is T => values.includes(value as T);
75
+
76
+ const readNativeClassification = (
77
+ error: object,
78
+ ): Classification | null | undefined => {
79
+ if (!("code" in error) || typeof error.code !== "string") return undefined;
80
+ const userInfo =
81
+ "userInfo" in error && typeof error.userInfo === "object"
82
+ ? (error.userInfo as Record<string, unknown> | null)
83
+ : null;
84
+ const { stage, reason, resource, transport, originCode } = userInfo ?? {};
85
+ // Native classifies every failure of its download and install; a rejection
86
+ // without it, such as a stale selection, is not an update failure.
87
+ if (!oneOf(STAGES, stage) || !oneOf(REASONS, reason)) return null;
88
+ const httpStatus = Number(userInfo?.httpStatus);
89
+ return {
90
+ stage,
91
+ reason,
92
+ ...(oneOf(RESOURCES, resource) ? { resource } : {}),
93
+ ...(reason === "http" && Number.isSafeInteger(httpStatus)
94
+ ? { httpStatus }
95
+ : {}),
96
+ ...(reason === "http" &&
97
+ typeof originCode === "string" &&
98
+ ORIGIN_CODE.test(originCode)
99
+ ? { originCode }
100
+ : {}),
101
+ ...(reason === "network" && oneOf(TRANSPORTS, transport)
102
+ ? { transport }
103
+ : {}),
104
+ };
105
+ };
106
+
107
+ /**
108
+ * Where and why an update failed, or null when the error is not an update
109
+ * failure. Native rejections carry their own classification; an error the
110
+ * SDK's JavaScript raised happened in `stage`, fetching `resource` when one
111
+ * is given.
112
+ */
113
+ export const classifyUpdateError = (
114
+ error: unknown,
115
+ stage: UpdateErrorStage,
116
+ resource?: UpdateErrorResource,
117
+ ): Classification | null => {
118
+ if (typeof error === "object" && error !== null) {
119
+ const native = readNativeClassification(error);
120
+ if (native !== undefined) return native;
121
+ }
122
+ const scope = {
123
+ stage,
124
+ ...(resource === undefined ? {} : { resource }),
125
+ };
126
+ // Names, not classes, so an error from another copy of a module still
127
+ // classifies, as it does across test module resets.
128
+ const name = error instanceof Error ? error.name : null;
129
+ // A selection that became stale is a race between checks, not a failure.
130
+ if (name === "StaleReleaseCatalogError") return null;
131
+ if (name === "UpdateHttpError") {
132
+ return {
133
+ ...scope,
134
+ reason: "http",
135
+ httpStatus: (error as UpdateHttpError).status,
136
+ };
137
+ }
138
+ if (name === "InvalidUpdateResponseError" || name === "SyntaxError") {
139
+ return { ...scope, reason: "invalid_response" };
140
+ }
141
+ if (error instanceof Error && error.message === "Request timed out") {
142
+ return { ...scope, reason: "network", transport: "timeout" };
143
+ }
144
+ if (name === "AbortError") {
145
+ return { ...scope, reason: "network", transport: "cancelled" };
146
+ }
147
+ if (name === "TypeError") {
148
+ // fetch rejects with a TypeError when no response arrives, without
149
+ // saying why.
150
+ return { ...scope, reason: "network" };
151
+ }
152
+ return { ...scope, reason: "unknown" };
153
+ };
package/src/wrap.tsx CHANGED
@@ -1,11 +1,12 @@
1
1
  import React, { useEffect, useState } from "react";
2
2
 
3
+ import { handleNotifyAppReady } from "./appReady";
3
4
  import { checkForUpdate } from "./checkForUpdate";
4
5
  import { useEventCallback } from "./hooks/useEventCallback";
5
6
  import { getUpdateId, reload } from "./native";
6
- import { handleNotifyAppReady } from "./notifyAppReadyInsights";
7
7
  import { useHotUpdaterStore } from "./store";
8
8
  import type {
9
+ HotUpdaterFallbackComponentProps,
9
10
  InternalInitOptions,
10
11
  InternalWrapOptions,
11
12
  UpdateStatus,
@@ -32,11 +33,46 @@ export function wrap(
32
33
  ) => React.ComponentType<P> {
33
34
  const { reloadOnForceUpdate = true, ...restOptions } = options;
34
35
 
36
+ // Progress is subscribed only where it is rendered or reported, so progress
37
+ // events don't re-render the wrapped app.
38
+ const ProgressReporter = ({
39
+ onProgress,
40
+ }: {
41
+ onProgress: (progress: number) => void;
42
+ }) => {
43
+ const progress = useHotUpdaterStore((state) => state.progress);
44
+
45
+ useEffect(() => {
46
+ onProgress(progress);
47
+ }, [progress]);
48
+
49
+ return null;
50
+ };
51
+
52
+ const FallbackWithProgress = ({
53
+ Fallback,
54
+ status,
55
+ message,
56
+ }: {
57
+ Fallback: React.FC<HotUpdaterFallbackComponentProps>;
58
+ status: HotUpdaterFallbackComponentProps["status"];
59
+ message: string | null;
60
+ }) => {
61
+ const progressState = useHotUpdaterStore((state) => state);
62
+
63
+ return (
64
+ <Fallback
65
+ artifactType={progressState.artifactType}
66
+ details={progressState.details}
67
+ progress={progressState.progress}
68
+ status={status}
69
+ message={message}
70
+ />
71
+ );
72
+ };
73
+
35
74
  return <P extends object>(WrappedComponent: React.ComponentType<P>) => {
36
75
  const HotUpdaterHOC: React.FC<P> = (props: P) => {
37
- const progressState = useHotUpdaterStore((state) => state);
38
- const progress = progressState.progress;
39
-
40
76
  const [message, setMessage] = useState<string | null>(null);
41
77
  const [updateStatus, setUpdateStatus] =
42
78
  useState<UpdateStatus>("CHECK_FOR_UPDATE");
@@ -45,8 +81,8 @@ export function wrap(
45
81
  try {
46
82
  setUpdateStatus("CHECK_FOR_UPDATE");
47
83
 
84
+ const readiness = handleNotifyAppReady(restOptions);
48
85
  const updateInfo = await checkForUpdate({
49
- insights: restOptions.insights,
50
86
  client: restOptions.client,
51
87
  updateStrategy: restOptions.updateStrategy,
52
88
  requestHeaders: restOptions.requestHeaders,
@@ -54,6 +90,7 @@ export function wrap(
54
90
  onError: restOptions.onError,
55
91
  });
56
92
 
93
+ await readiness;
57
94
  setMessage(updateInfo?.message ?? null);
58
95
 
59
96
  if (!updateInfo) {
@@ -111,39 +148,33 @@ export function wrap(
111
148
  }
112
149
  });
113
150
 
114
- useEffect(() => {
115
- restOptions.onProgress?.(progress);
116
- }, [progress]);
117
-
118
- // Read the native launch report after the first render commit.
119
- useEffect(() => {
120
- void handleNotifyAppReady(restOptions);
121
- }, []);
122
-
123
151
  // Start update check
124
152
  useEffect(() => {
125
153
  initHotUpdater();
126
154
  }, []);
127
155
 
128
- if (
156
+ const content =
129
157
  restOptions.fallbackComponent &&
130
- updateStatus !== "UPDATE_PROCESS_COMPLETED"
131
- ) {
132
- const Fallback = restOptions.fallbackComponent;
133
- return (
134
- <Fallback
135
- artifactType={progressState.artifactType}
136
- details={progressState.details}
137
- downloadedBytes={progressState.downloadedBytes}
138
- progress={progress}
158
+ updateStatus !== "UPDATE_PROCESS_COMPLETED" ? (
159
+ <FallbackWithProgress
160
+ Fallback={restOptions.fallbackComponent}
139
161
  status={updateStatus}
140
162
  message={message}
141
- totalBytes={progressState.totalBytes}
142
163
  />
164
+ ) : (
165
+ <WrappedComponent {...props} />
143
166
  );
167
+
168
+ if (!restOptions.onProgress) {
169
+ return content;
144
170
  }
145
171
 
146
- return <WrappedComponent {...props} />;
172
+ return (
173
+ <>
174
+ {content}
175
+ <ProgressReporter onProgress={restOptions.onProgress} />
176
+ </>
177
+ );
147
178
  };
148
179
 
149
180
  return HotUpdaterHOC as React.ComponentType<P>;
package/src/wrap.types.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type React from "react";
2
2
 
3
+ import type { HotUpdaterClientPlugin } from "./clientPlugin";
3
4
  import type { HotUpdaterError } from "./error";
4
5
  import type { HotUpdaterHttpClient } from "./httpClient";
5
6
  import type { NotifyAppReadyResult } from "./native";
@@ -21,8 +22,6 @@ export type UpdateStatus =
21
22
  export type HotUpdaterFallbackComponentProps = {
22
23
  status: Exclude<UpdateStatus, "UPDATE_PROCESS_COMPLETED">;
23
24
  progress: number;
24
- downloadedBytes: HotUpdaterState["downloadedBytes"];
25
- totalBytes: HotUpdaterState["totalBytes"];
26
25
  message: string | null;
27
26
  artifactType: HotUpdaterState["artifactType"];
28
27
  details: HotUpdaterState["details"];
@@ -30,11 +29,12 @@ export type HotUpdaterFallbackComponentProps = {
30
29
 
31
30
  interface CommonHotUpdaterOptions {
32
31
  /**
33
- * Sends app-ready transitions and same-Bundle Release adoptions to the
34
- * configured server. Defaults to `true`; set to `false` to disable client
35
- * reporting.
32
+ * Client plugins, such as `insights()` from `@hot-updater/react-native`.
33
+ * Each plugin's `setup` runs
34
+ * once, and its hooks observe launches, update checks, downloads, and
35
+ * update failures. Plugin ids must be unique.
36
36
  */
37
- insights?: boolean;
37
+ plugins?: readonly HotUpdaterClientPlugin[];
38
38
  /** Base URL of a server exposing the Hot Updater v1 client HTTP protocol. */
39
39
  baseURL: HotUpdaterBaseURL;
40
40
  requestHeaders?: Record<string, string>;
@@ -56,7 +56,6 @@ export type HotUpdaterInitOptions = CommonHotUpdaterOptions;
56
56
  export type HotUpdaterOptions = AutoUpdateOptions;
57
57
 
58
58
  type InternalCommonOptions = {
59
- insights?: boolean;
60
59
  client: HotUpdaterHttpClient;
61
60
  requestHeaders?: Record<string, string>;
62
61
  requestTimeout?: number;
@@ -1,89 +0,0 @@
1
- package com.hotupdater
2
-
3
- import android.util.Log
4
- import java.io.File
5
-
6
- /**
7
- * Unified decompression service that uses Strategy pattern to handle multiple compression formats.
8
- * Automatically detects format by trying each strategy's validation and delegates to appropriate decompression strategy.
9
- */
10
- class DecompressService {
11
- companion object {
12
- private const val TAG = "DecompressService"
13
- }
14
-
15
- // Strategies with reliable file signatures that can be validated cheaply.
16
- // TAR.BR is attempted only as the final fallback because Brotli has no reliable magic bytes.
17
- private val signatureStrategies =
18
- listOf(
19
- ZipDecompressionStrategy(),
20
- TarGzDecompressionStrategy(),
21
- )
22
- private val tarBrStrategy = TarBrDecompressionStrategy()
23
-
24
- /**
25
- * Extracts a compressed file to the destination directory.
26
- * Automatically detects compression format by trying each strategy's validation.
27
- * @param filePath Path to the compressed file
28
- * @param destinationPath Path to the destination directory
29
- * @param progressCallback Callback for progress updates (0.0 - 1.0)
30
- * @return true if extraction was successful, false otherwise
31
- */
32
- fun extractZipFile(
33
- filePath: String,
34
- destinationPath: String,
35
- progressCallback: (Double) -> Unit,
36
- ): Boolean {
37
- // Collect file information for better error messages
38
- val file = File(filePath)
39
- val fileName = file.name
40
- val fileSize = if (file.exists()) file.length() else 0L
41
-
42
- // Try each signature-based strategy first.
43
- for (strategy in signatureStrategies) {
44
- if (strategy.isValid(filePath)) {
45
- Log.d(TAG, "Using strategy for $fileName")
46
- return strategy.decompress(filePath, destinationPath, progressCallback)
47
- }
48
- }
49
-
50
- Log.d(TAG, "No ZIP/TAR.GZ signature matched for $fileName, trying TAR.BR fallback")
51
-
52
- if (tarBrStrategy.decompress(filePath, destinationPath, progressCallback)) {
53
- Log.d(TAG, "Using TAR.BR fallback for $fileName")
54
- return true
55
- }
56
-
57
- val errorMessage = createInvalidArchiveMessage(fileName, fileSize)
58
- Log.e(TAG, errorMessage)
59
- return false
60
- }
61
-
62
- /**
63
- * Validates if a file matches one of the signature-based archive formats.
64
- * @param filePath Path to the file to validate
65
- * @return true if the file is a valid compressed archive
66
- */
67
- fun isValidZipFile(filePath: String): Boolean {
68
- for (strategy in signatureStrategies) {
69
- if (strategy.isValid(filePath)) {
70
- return true
71
- }
72
- }
73
- Log.d(TAG, "No ZIP/TAR.GZ signature matched for file: $filePath. TAR.BR is handled during extraction fallback.")
74
- return false
75
- }
76
-
77
- private fun createInvalidArchiveMessage(
78
- fileName: String,
79
- fileSize: Long,
80
- ): String =
81
- """
82
- The downloaded bundle file is not a valid compressed archive: $fileName ($fileSize bytes)
83
-
84
- Supported formats:
85
- - ZIP archives (.zip)
86
- - GZIP compressed TAR archives (.tar.gz)
87
- - Brotli compressed TAR archives (.tar.br)
88
- """.trimIndent()
89
- }
@@ -1,26 +0,0 @@
1
- package com.hotupdater
2
-
3
- /**
4
- * Interface for decompression strategies
5
- */
6
- interface DecompressionStrategy {
7
- /**
8
- * Validates if a file can be decompressed by this strategy
9
- * @param filePath Path to the file to validate
10
- * @return true if the file is valid for this strategy
11
- */
12
- fun isValid(filePath: String): Boolean
13
-
14
- /**
15
- * Decompresses a file to the destination directory
16
- * @param filePath Path to the compressed file
17
- * @param destinationPath Path to the destination directory
18
- * @param progressCallback Callback for progress updates (0.0 - 1.0)
19
- * @return true if decompression was successful, false otherwise
20
- */
21
- fun decompress(
22
- filePath: String,
23
- destinationPath: String,
24
- progressCallback: (Double) -> Unit,
25
- ): Boolean
26
- }