@hot-updater/react-native 1.0.0-rc.2 → 1.0.0-rc.22

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 (291) 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 +125 -70
  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 +5 -2
  50. package/lib/commonjs/fetchJSON.js.map +1 -1
  51. package/lib/commonjs/httpClient.js +55 -92
  52. package/lib/commonjs/httpClient.js.map +1 -1
  53. package/lib/commonjs/index.js +68 -20
  54. package/lib/commonjs/index.js.map +1 -1
  55. package/lib/commonjs/native.js +82 -62
  56. package/lib/commonjs/native.js.map +1 -1
  57. package/lib/commonjs/pluginHost.js +44 -0
  58. package/lib/commonjs/pluginHost.js.map +1 -0
  59. package/lib/commonjs/releaseCatalogCache.js +20 -61
  60. package/lib/commonjs/releaseCatalogCache.js.map +1 -1
  61. package/lib/commonjs/sdkVersion.js +1 -1
  62. package/lib/commonjs/sdkVersion.js.map +1 -1
  63. package/lib/commonjs/specs/NativeHotUpdater.js.map +1 -1
  64. package/lib/commonjs/store.js +3 -10
  65. package/lib/commonjs/store.js.map +1 -1
  66. package/lib/commonjs/updateError.js +132 -0
  67. package/lib/commonjs/updateError.js.map +1 -0
  68. package/lib/commonjs/wrap.js +44 -27
  69. package/lib/commonjs/wrap.js.map +1 -1
  70. package/lib/module/appReady.js +103 -0
  71. package/lib/module/appReady.js.map +1 -0
  72. package/lib/module/checkForUpdate.js +118 -65
  73. package/lib/module/checkForUpdate.js.map +1 -1
  74. package/lib/module/clientPlugin.js +4 -0
  75. package/lib/module/clientPlugin.js.map +1 -0
  76. package/lib/module/error.js +4 -13
  77. package/lib/module/error.js.map +1 -1
  78. package/lib/module/fetchJSON.js +3 -1
  79. package/lib/module/fetchJSON.js.map +1 -1
  80. package/lib/module/httpClient.js +53 -90
  81. package/lib/module/httpClient.js.map +1 -1
  82. package/lib/module/index.js +55 -22
  83. package/lib/module/index.js.map +1 -1
  84. package/lib/module/native.js +74 -54
  85. package/lib/module/native.js.map +1 -1
  86. package/lib/module/pluginHost.js +35 -0
  87. package/lib/module/pluginHost.js.map +1 -0
  88. package/lib/module/releaseCatalogCache.js +16 -56
  89. package/lib/module/releaseCatalogCache.js.map +1 -1
  90. package/lib/module/sdkVersion.js +1 -1
  91. package/lib/module/sdkVersion.js.map +1 -1
  92. package/lib/module/specs/NativeHotUpdater.js.map +1 -1
  93. package/lib/module/store.js +3 -10
  94. package/lib/module/store.js.map +1 -1
  95. package/lib/module/updateError.js +126 -0
  96. package/lib/module/updateError.js.map +1 -0
  97. package/lib/module/wrap.js +45 -28
  98. package/lib/module/wrap.js.map +1 -1
  99. package/lib/typescript/commonjs/appReady.d.ts +23 -0
  100. package/lib/typescript/commonjs/appReady.d.ts.map +1 -0
  101. package/lib/typescript/commonjs/checkForUpdate.d.ts +16 -4
  102. package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
  103. package/lib/typescript/commonjs/clientPlugin.d.ts +2 -0
  104. package/lib/typescript/commonjs/clientPlugin.d.ts.map +1 -0
  105. package/lib/typescript/commonjs/error.d.ts +4 -13
  106. package/lib/typescript/commonjs/error.d.ts.map +1 -1
  107. package/lib/typescript/commonjs/fetchJSON.d.ts +3 -0
  108. package/lib/typescript/commonjs/fetchJSON.d.ts.map +1 -1
  109. package/lib/typescript/commonjs/httpClient.d.ts +3 -32
  110. package/lib/typescript/commonjs/httpClient.d.ts.map +1 -1
  111. package/lib/typescript/commonjs/index.d.ts +7 -12
  112. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  113. package/lib/typescript/commonjs/native.d.ts +33 -23
  114. package/lib/typescript/commonjs/native.d.ts.map +1 -1
  115. package/lib/typescript/commonjs/pluginHost.d.ts +4 -0
  116. package/lib/typescript/commonjs/pluginHost.d.ts.map +1 -0
  117. package/lib/typescript/commonjs/releaseCatalogCache.d.ts +6 -14
  118. package/lib/typescript/commonjs/releaseCatalogCache.d.ts.map +1 -1
  119. package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
  120. package/lib/typescript/commonjs/sdkVersion.d.ts.map +1 -1
  121. package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts +42 -47
  122. package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts.map +1 -1
  123. package/lib/typescript/commonjs/store.d.ts +1 -3
  124. package/lib/typescript/commonjs/store.d.ts.map +1 -1
  125. package/lib/typescript/commonjs/types.d.ts +1 -1
  126. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  127. package/lib/typescript/commonjs/updateError.d.ts +26 -0
  128. package/lib/typescript/commonjs/updateError.d.ts.map +1 -0
  129. package/lib/typescript/commonjs/wrap.d.ts.map +1 -1
  130. package/lib/typescript/commonjs/wrap.types.d.ts +6 -7
  131. package/lib/typescript/commonjs/wrap.types.d.ts.map +1 -1
  132. package/lib/typescript/module/appReady.d.ts +23 -0
  133. package/lib/typescript/module/appReady.d.ts.map +1 -0
  134. package/lib/typescript/module/checkForUpdate.d.ts +16 -4
  135. package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
  136. package/lib/typescript/module/clientPlugin.d.ts +2 -0
  137. package/lib/typescript/module/clientPlugin.d.ts.map +1 -0
  138. package/lib/typescript/module/error.d.ts +4 -13
  139. package/lib/typescript/module/error.d.ts.map +1 -1
  140. package/lib/typescript/module/fetchJSON.d.ts +3 -0
  141. package/lib/typescript/module/fetchJSON.d.ts.map +1 -1
  142. package/lib/typescript/module/httpClient.d.ts +3 -32
  143. package/lib/typescript/module/httpClient.d.ts.map +1 -1
  144. package/lib/typescript/module/index.d.ts +7 -12
  145. package/lib/typescript/module/index.d.ts.map +1 -1
  146. package/lib/typescript/module/native.d.ts +33 -23
  147. package/lib/typescript/module/native.d.ts.map +1 -1
  148. package/lib/typescript/module/pluginHost.d.ts +4 -0
  149. package/lib/typescript/module/pluginHost.d.ts.map +1 -0
  150. package/lib/typescript/module/releaseCatalogCache.d.ts +6 -14
  151. package/lib/typescript/module/releaseCatalogCache.d.ts.map +1 -1
  152. package/lib/typescript/module/sdkVersion.d.ts +1 -1
  153. package/lib/typescript/module/sdkVersion.d.ts.map +1 -1
  154. package/lib/typescript/module/specs/NativeHotUpdater.d.ts +42 -47
  155. package/lib/typescript/module/specs/NativeHotUpdater.d.ts.map +1 -1
  156. package/lib/typescript/module/store.d.ts +1 -3
  157. package/lib/typescript/module/store.d.ts.map +1 -1
  158. package/lib/typescript/module/types.d.ts +1 -1
  159. package/lib/typescript/module/types.d.ts.map +1 -1
  160. package/lib/typescript/module/updateError.d.ts +26 -0
  161. package/lib/typescript/module/updateError.d.ts.map +1 -0
  162. package/lib/typescript/module/wrap.d.ts.map +1 -1
  163. package/lib/typescript/module/wrap.types.d.ts +6 -7
  164. package/lib/typescript/module/wrap.types.d.ts.map +1 -1
  165. package/package.json +7 -4
  166. package/src/appReady.ts +149 -0
  167. package/src/checkForUpdate.ts +152 -89
  168. package/src/clientPlugin.ts +17 -0
  169. package/src/error.ts +4 -14
  170. package/src/fetchJSON.ts +5 -1
  171. package/src/httpClient.ts +78 -157
  172. package/src/index.ts +87 -29
  173. package/src/native.ts +109 -104
  174. package/src/pluginHost.ts +45 -0
  175. package/src/releaseCatalogCache.ts +26 -140
  176. package/src/sdkVersion.ts +1 -1
  177. package/src/specs/NativeHotUpdater.ts +41 -48
  178. package/src/store.ts +2 -23
  179. package/src/types.ts +1 -1
  180. package/src/updateError.ts +153 -0
  181. package/src/wrap.tsx +59 -28
  182. package/src/wrap.types.ts +6 -7
  183. package/android/src/main/java/com/hotupdater/DecompressService.kt +0 -89
  184. package/android/src/main/java/com/hotupdater/DecompressionStrategy.kt +0 -26
  185. package/android/src/main/java/com/hotupdater/TarBrDecompressionStrategy.kt +0 -117
  186. package/android/src/main/java/com/hotupdater/TarGzDecompressionStrategy.kt +0 -117
  187. package/android/src/main/java/com/hotupdater/ZipDecompressionStrategy.kt +0 -192
  188. package/android/src/test/java/com/hotupdater/BsdiffPatchTest.kt +0 -46
  189. package/android/src/test/java/com/hotupdater/BundleFileStorageServiceTest.kt +0 -799
  190. package/android/src/test/java/com/hotupdater/HotUpdaterImplTest.kt +0 -273
  191. package/android/src/test/java/com/hotupdater/NativeConfigUtilsTest.kt +0 -20
  192. package/android/src/test/java/com/hotupdater/OkHttpDownloadServiceTest.kt +0 -111
  193. package/android/src/test/java/com/hotupdater/RelativePathResolverTest.kt +0 -41
  194. package/android/src/test/java/com/hotupdater/ReleaseCatalogCacheServiceTest.kt +0 -118
  195. package/android/src/test/java/com/hotupdater/TarArchiveInputStreamTest.kt +0 -68
  196. package/ios/HotUpdater/Internal/ArchiveExtractionUtilities.swift +0 -178
  197. package/ios/HotUpdater/Internal/DecompressService.swift +0 -112
  198. package/ios/HotUpdater/Internal/DecompressionStrategy.swift +0 -22
  199. package/ios/HotUpdater/Internal/StreamingTarArchiveExtractor.swift +0 -370
  200. package/ios/HotUpdater/Internal/TarBrDecompressionStrategy.swift +0 -39
  201. package/ios/HotUpdater/Internal/TarGzDecompressionStrategy.swift +0 -59
  202. package/ios/HotUpdater/Internal/ZipArchiveExtractor.swift +0 -482
  203. package/ios/HotUpdater/Internal/ZipDecompressionStrategy.swift +0 -56
  204. package/lib/commonjs/catalogCacheNative.spec.js +0 -31
  205. package/lib/commonjs/catalogCacheNative.spec.js.map +0 -1
  206. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js +0 -604
  207. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js.map +0 -1
  208. package/lib/commonjs/httpClient.spec.js +0 -102
  209. package/lib/commonjs/httpClient.spec.js.map +0 -1
  210. package/lib/commonjs/index.spec.js +0 -298
  211. package/lib/commonjs/index.spec.js.map +0 -1
  212. package/lib/commonjs/iosInterop.spec.js +0 -18
  213. package/lib/commonjs/iosInterop.spec.js.map +0 -1
  214. package/lib/commonjs/native.spec.js +0 -795
  215. package/lib/commonjs/native.spec.js.map +0 -1
  216. package/lib/commonjs/notifyAppReadyInsights.boundary.spec.js +0 -218
  217. package/lib/commonjs/notifyAppReadyInsights.boundary.spec.js.map +0 -1
  218. package/lib/commonjs/notifyAppReadyInsights.js +0 -133
  219. package/lib/commonjs/notifyAppReadyInsights.js.map +0 -1
  220. package/lib/commonjs/notifyAppReadyInsights.spec.js +0 -246
  221. package/lib/commonjs/notifyAppReadyInsights.spec.js.map +0 -1
  222. package/lib/commonjs/notifyAppReadyInsights.test-utils.js +0 -24
  223. package/lib/commonjs/notifyAppReadyInsights.test-utils.js.map +0 -1
  224. package/lib/commonjs/notifyAppReadyInsights.transport.spec.js +0 -117
  225. package/lib/commonjs/notifyAppReadyInsights.transport.spec.js.map +0 -1
  226. package/lib/commonjs/releaseCatalogCache.spec.js +0 -195
  227. package/lib/commonjs/releaseCatalogCache.spec.js.map +0 -1
  228. package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js +0 -64
  229. package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js.map +0 -1
  230. package/lib/commonjs/store.notification.spec.js +0 -76
  231. package/lib/commonjs/store.notification.spec.js.map +0 -1
  232. package/lib/commonjs/store.spec.js +0 -316
  233. package/lib/commonjs/store.spec.js.map +0 -1
  234. package/lib/commonjs/wrap.spec.js +0 -296
  235. package/lib/commonjs/wrap.spec.js.map +0 -1
  236. package/lib/module/catalogCacheNative.spec.js +0 -31
  237. package/lib/module/catalogCacheNative.spec.js.map +0 -1
  238. package/lib/module/checkForUpdate.releaseCatalog.spec.js +0 -603
  239. package/lib/module/checkForUpdate.releaseCatalog.spec.js.map +0 -1
  240. package/lib/module/httpClient.spec.js +0 -102
  241. package/lib/module/httpClient.spec.js.map +0 -1
  242. package/lib/module/index.spec.js +0 -297
  243. package/lib/module/index.spec.js.map +0 -1
  244. package/lib/module/iosInterop.spec.js +0 -18
  245. package/lib/module/iosInterop.spec.js.map +0 -1
  246. package/lib/module/native.spec.js +0 -794
  247. package/lib/module/native.spec.js.map +0 -1
  248. package/lib/module/notifyAppReadyInsights.boundary.spec.js +0 -217
  249. package/lib/module/notifyAppReadyInsights.boundary.spec.js.map +0 -1
  250. package/lib/module/notifyAppReadyInsights.js +0 -128
  251. package/lib/module/notifyAppReadyInsights.js.map +0 -1
  252. package/lib/module/notifyAppReadyInsights.spec.js +0 -245
  253. package/lib/module/notifyAppReadyInsights.spec.js.map +0 -1
  254. package/lib/module/notifyAppReadyInsights.test-utils.js +0 -18
  255. package/lib/module/notifyAppReadyInsights.test-utils.js.map +0 -1
  256. package/lib/module/notifyAppReadyInsights.transport.spec.js +0 -116
  257. package/lib/module/notifyAppReadyInsights.transport.spec.js.map +0 -1
  258. package/lib/module/releaseCatalogCache.spec.js +0 -195
  259. package/lib/module/releaseCatalogCache.spec.js.map +0 -1
  260. package/lib/module/releaseCatalogCacheNativeContract.spec.js +0 -64
  261. package/lib/module/releaseCatalogCacheNativeContract.spec.js.map +0 -1
  262. package/lib/module/store.notification.spec.js +0 -77
  263. package/lib/module/store.notification.spec.js.map +0 -1
  264. package/lib/module/store.spec.js +0 -315
  265. package/lib/module/store.spec.js.map +0 -1
  266. package/lib/module/wrap.spec.js +0 -295
  267. package/lib/module/wrap.spec.js.map +0 -1
  268. package/lib/typescript/commonjs/notifyAppReadyInsights.d.ts +0 -13
  269. package/lib/typescript/commonjs/notifyAppReadyInsights.d.ts.map +0 -1
  270. package/lib/typescript/commonjs/notifyAppReadyInsights.test-utils.d.ts +0 -8
  271. package/lib/typescript/commonjs/notifyAppReadyInsights.test-utils.d.ts.map +0 -1
  272. package/lib/typescript/module/notifyAppReadyInsights.d.ts +0 -13
  273. package/lib/typescript/module/notifyAppReadyInsights.d.ts.map +0 -1
  274. package/lib/typescript/module/notifyAppReadyInsights.test-utils.d.ts +0 -8
  275. package/lib/typescript/module/notifyAppReadyInsights.test-utils.d.ts.map +0 -1
  276. package/src/catalogCacheNative.spec.ts +0 -63
  277. package/src/checkForUpdate.releaseCatalog.spec.ts +0 -596
  278. package/src/httpClient.spec.ts +0 -132
  279. package/src/index.spec.ts +0 -331
  280. package/src/iosInterop.spec.ts +0 -30
  281. package/src/native.spec.ts +0 -855
  282. package/src/notifyAppReadyInsights.boundary.spec.ts +0 -234
  283. package/src/notifyAppReadyInsights.spec.ts +0 -243
  284. package/src/notifyAppReadyInsights.test-utils.ts +0 -31
  285. package/src/notifyAppReadyInsights.transport.spec.ts +0 -130
  286. package/src/notifyAppReadyInsights.ts +0 -194
  287. package/src/releaseCatalogCache.spec.ts +0 -282
  288. package/src/releaseCatalogCacheNativeContract.spec.ts +0 -80
  289. package/src/store.notification.spec.ts +0 -92
  290. package/src/store.spec.ts +0 -372
  291. package/src/wrap.spec.ts +0 -367
@@ -84,6 +84,7 @@ public struct BundleMetadata: Codable {
84
84
  var stableSelection: PersistedSelection?
85
85
  var stagingSelection: PersistedSelection?
86
86
  var verificationPending: Bool
87
+ var launchInProgress: Bool
87
88
  var pendingTransition: PendingBundleTransition?
88
89
  var pendingSelectionTransition: PendingSelectionTransition?
89
90
  var highestSeenCatalogs: [String: CatalogHighWater]
@@ -98,6 +99,7 @@ public struct BundleMetadata: Codable {
98
99
  case stableSelection = "stable_selection"
99
100
  case stagingSelection = "staging_selection"
100
101
  case verificationPending = "verification_pending"
102
+ case launchInProgress = "launch_in_progress"
101
103
  case pendingTransition = "pending_transition"
102
104
  case pendingSelectionTransition = "pending_selection_transition"
103
105
  case highestSeenCatalogs = "highest_seen_catalogs"
@@ -113,6 +115,7 @@ public struct BundleMetadata: Codable {
113
115
  stableSelection: PersistedSelection? = nil,
114
116
  stagingSelection: PersistedSelection? = nil,
115
117
  verificationPending: Bool = false,
118
+ launchInProgress: Bool = false,
116
119
  pendingTransition: PendingBundleTransition? = nil,
117
120
  pendingSelectionTransition: PendingSelectionTransition? = nil,
118
121
  highestSeenCatalogs: [String: CatalogHighWater] = [:],
@@ -126,6 +129,7 @@ public struct BundleMetadata: Codable {
126
129
  self.stableSelection = stableSelection
127
130
  self.stagingSelection = stagingSelection
128
131
  self.verificationPending = verificationPending
132
+ self.launchInProgress = launchInProgress
129
133
  self.pendingTransition = pendingTransition
130
134
  self.pendingSelectionTransition = pendingSelectionTransition
131
135
  self.highestSeenCatalogs = highestSeenCatalogs
@@ -144,6 +148,7 @@ public struct BundleMetadata: Codable {
144
148
  stagingSelection = try values.decodeIfPresent(PersistedSelection.self, forKey: .stagingSelection)
145
149
  ?? stagingBundleId.map(PersistedSelection.legacyBundle)
146
150
  verificationPending = try values.decodeIfPresent(Bool.self, forKey: .verificationPending) ?? false
151
+ launchInProgress = try values.decodeIfPresent(Bool.self, forKey: .launchInProgress) ?? false
147
152
  pendingTransition = try values.decodeIfPresent(PendingBundleTransition.self, forKey: .pendingTransition)
148
153
  pendingSelectionTransition = try values.decodeIfPresent(PendingSelectionTransition.self, forKey: .pendingSelectionTransition)
149
154
  highestSeenCatalogs = try values.decodeIfPresent([String: CatalogHighWater].self, forKey: .highestSeenCatalogs) ?? [:]
@@ -378,6 +383,8 @@ public struct LaunchReport: Codable {
378
383
  }
379
384
  }
380
385
 
386
+ /// The random id created once per app installation. It lives in
387
+ /// `NoBackupStorage`, so a device backup never carries it to another device.
381
388
  public struct InstallIdentity: Codable {
382
389
  static let installIdentityFilename = "install-identity.json"
383
390
 
@@ -407,11 +414,7 @@ public struct InstallIdentity: Codable {
407
414
  let encoder = JSONEncoder()
408
415
  encoder.outputFormatting = .prettyPrinted
409
416
  let data = try encoder.encode(self)
410
- let directory = file.deletingLastPathComponent()
411
- if !FileManager.default.fileExists(atPath: directory.path) {
412
- try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
413
- }
414
- try data.write(to: file)
417
+ try NoBackupStorage.write(data, to: file)
415
418
  return true
416
419
  } catch {
417
420
  print("[InstallIdentity] Failed to save install identity: \(error)")
@@ -419,51 +422,3 @@ public struct InstallIdentity: Codable {
419
422
  }
420
423
  }
421
424
  }
422
-
423
- public struct UserIdentity: Codable {
424
- static let userIdentityFilename = "user-identity.json"
425
-
426
- let userId: String?
427
- let username: String?
428
-
429
- init(userId: String?, username: String?) {
430
- self.userId = userId
431
- self.username = username
432
- }
433
-
434
- var isEmpty: Bool {
435
- userId == nil && username == nil
436
- }
437
-
438
- static func load(from file: URL) -> UserIdentity? {
439
- guard FileManager.default.fileExists(atPath: file.path) else {
440
- return nil
441
- }
442
-
443
- do {
444
- let data = try Data(contentsOf: file)
445
- let identity = try JSONDecoder().decode(UserIdentity.self, from: data)
446
- return identity.isEmpty ? nil : identity
447
- } catch {
448
- print("[UserIdentity] Failed to load user identity: \(error)")
449
- return nil
450
- }
451
- }
452
-
453
- func save(to file: URL) -> Bool {
454
- do {
455
- let encoder = JSONEncoder()
456
- encoder.outputFormatting = .prettyPrinted
457
- let data = try encoder.encode(self)
458
- let directory = file.deletingLastPathComponent()
459
- if !FileManager.default.fileExists(atPath: directory.path) {
460
- try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
461
- }
462
- try data.write(to: file)
463
- return true
464
- } catch {
465
- print("[UserIdentity] Failed to save user identity: \(error)")
466
- return false
467
- }
468
- }
469
- }
@@ -17,6 +17,45 @@ protocol FileSystemService {
17
17
  func contentsOfDirectory(atPath path: String) throws -> [String]
18
18
  func attributesOfItem(atPath path: String) throws -> [FileAttributeKey: Any]
19
19
  func documentsPath() -> String
20
+ /// Base directory for data that lives as long as the installation.
21
+ func applicationSupportPath() -> String
22
+ }
23
+
24
+ /// `Application Support/HotUpdater`: data the SDK keeps for the life of an
25
+ /// installation, such as the install id and plugin storage. Device backups
26
+ /// skip it, so restoring a backup onto another device never copies it there.
27
+ enum NoBackupStorage {
28
+ static let directoryName = "HotUpdater"
29
+
30
+ static func directory(in fileSystem: FileSystemService) -> URL {
31
+ URL(fileURLWithPath: fileSystem.applicationSupportPath(), isDirectory: true)
32
+ .appendingPathComponent(directoryName, isDirectory: true)
33
+ }
34
+
35
+ /// Atomically replaces `file` with `data`, creating its directory when
36
+ /// needed, and excludes the directory and the file from device backups.
37
+ static func write(_ data: Data, to file: URL) throws {
38
+ let directory = file.deletingLastPathComponent()
39
+ try FileManager.default.createDirectory(
40
+ at: directory,
41
+ withIntermediateDirectories: true
42
+ )
43
+ excludeFromBackup(directory)
44
+ try data.write(to: file, options: .atomic)
45
+ // An atomic write replaces the file, which drops its previous flag.
46
+ excludeFromBackup(file)
47
+ }
48
+
49
+ static func excludeFromBackup(_ url: URL) {
50
+ var url = url
51
+ var values = URLResourceValues()
52
+ values.isExcludedFromBackup = true
53
+ do {
54
+ try url.setResourceValues(values)
55
+ } catch {
56
+ NSLog("[NoBackupStorage] Failed to exclude \(url.path) from backups: \(error)")
57
+ }
58
+ }
20
59
  }
21
60
 
22
61
  class FileManagerService: FileSystemService {
@@ -89,4 +128,13 @@ class FileManagerService: FileSystemService {
89
128
  return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
90
129
  #endif
91
130
  }
131
+
132
+ func applicationSupportPath() -> String {
133
+ #if os(tvOS)
134
+ // tvOS apps can only write purgeable files, so use Caches like documentsPath().
135
+ return NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
136
+ #else
137
+ return NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)[0]
138
+ #endif
139
+ }
92
140
  }
@@ -0,0 +1,64 @@
1
+ import Foundation
2
+
3
+ enum FileUtilities {
4
+ static func readUpToCount(from handle: FileHandle, count: Int) throws -> Data? {
5
+ guard count >= 0 else {
6
+ throw NSError(
7
+ domain: "FileUtilities",
8
+ code: 1,
9
+ userInfo: [NSLocalizedDescriptionKey: "Invalid read size: \(count)"]
10
+ )
11
+ }
12
+
13
+ if count == 0 {
14
+ return Data()
15
+ }
16
+
17
+ if #available(macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4, *) {
18
+ return try handle.read(upToCount: count)
19
+ }
20
+
21
+ return handle.readData(ofLength: count)
22
+ }
23
+
24
+ static func normalizedRelativePath(from rawPath: String) -> String? {
25
+ let candidate = rawPath.trimmingCharacters(in: .whitespacesAndNewlines)
26
+ guard !candidate.isEmpty,
27
+ !candidate.contains("\0"),
28
+ !candidate.contains("\\"),
29
+ !candidate.hasPrefix("/"),
30
+ candidate.range(of: #"^[A-Za-z]:"#, options: .regularExpression) == nil
31
+ else {
32
+ return nil
33
+ }
34
+
35
+ let components = candidate.split(separator: "/").map(String.init)
36
+ guard !components.isEmpty,
37
+ components.count == candidate.split(separator: "/", omittingEmptySubsequences: false).count,
38
+ !components.contains(".."),
39
+ !components.contains(".")
40
+ else {
41
+ return nil
42
+ }
43
+
44
+ return components.joined(separator: "/")
45
+ }
46
+
47
+ static func fileURL(for relativePath: String, destinationRoot: String) throws -> URL {
48
+ let rootURL = URL(fileURLWithPath: destinationRoot, isDirectory: true)
49
+ let targetURL = rootURL.appendingPathComponent(relativePath)
50
+ let standardizedRoot = rootURL.standardizedFileURL.path
51
+ let standardizedTarget = targetURL.standardizedFileURL.path
52
+
53
+ guard standardizedTarget == standardizedRoot ||
54
+ standardizedTarget.hasPrefix(standardizedRoot + "/") else {
55
+ throw NSError(
56
+ domain: "FileUtilities",
57
+ code: 2,
58
+ userInfo: [NSLocalizedDescriptionKey: "Path traversal attempt detected: \(relativePath)"]
59
+ )
60
+ }
61
+
62
+ return targetURL
63
+ }
64
+ }
@@ -7,7 +7,6 @@
7
7
  #import "React/RCTConstants.h"
8
8
  #import "React/RCTRootView.h"
9
9
  #import "React/RCTUtils.h" // Needed for RCTPromiseResolveBlock/RejectBlock in Swift
10
- #import <SSZipArchive/SSZipArchive.h>
11
10
  #import "BsdiffPatchBridge.h"
12
11
 
13
12
  @interface HotUpdaterRecoverySignalBridge : NSObject
@@ -274,8 +274,6 @@ extern "C" void *HotUpdaterCopyMinBundleId(void)
274
274
 
275
275
 
276
276
  // Define Notification names used for observing Swift Core
277
- NSNotificationName const HotUpdaterDownloadProgressUpdateNotification = @"HotUpdaterDownloadProgressUpdate";
278
- NSNotificationName const HotUpdaterDownloadDidFinishNotification = @"HotUpdaterDownloadDidFinish";
279
277
  NSNotificationName const HotUpdaterUpdateProgressDidChangeNotification = @"HotUpdaterUpdateProgressDidChange";
280
278
 
281
279
  @interface HotUpdaterRecoverySignalBridge : NSObject
@@ -300,8 +298,6 @@ NSNotificationName const HotUpdaterUpdateProgressDidChangeNotification = @"HotUp
300
298
 
301
299
  @implementation HotUpdater {
302
300
  bool hasListeners;
303
- // Keep track of tasks ONLY for removing observers when this ObjC instance is invalidated
304
- NSMutableSet<NSURLSessionTask *> *observedTasks; // Changed to NSURLSessionTask for broader compatibility if needed
305
301
  }
306
302
 
307
303
  @synthesize bridge = _bridge;
@@ -314,16 +310,10 @@ NSNotificationName const HotUpdaterUpdateProgressDidChangeNotification = @"HotUp
314
310
  - (instancetype)init {
315
311
  self = [super init];
316
312
  if (self) {
317
- observedTasks = [NSMutableSet set];
318
-
319
313
  [[NSNotificationCenter defaultCenter] addObserver:self
320
314
  selector:@selector(handleDownloadProgress:)
321
315
  name:HotUpdaterUpdateProgressDidChangeNotification
322
316
  object:nil];
323
- [[NSNotificationCenter defaultCenter] addObserver:self
324
- selector:@selector(handleDownloadCompletion:)
325
- name:HotUpdaterDownloadDidFinishNotification
326
- object:nil];
327
317
 
328
318
  _lastUpdateTime = 0;
329
319
  }
@@ -349,7 +339,6 @@ NSNotificationName const HotUpdaterUpdateProgressDidChangeNotification = @"HotUp
349
339
  if (gHotUpdaterBridge == self.bridge) {
350
340
  gHotUpdaterBridge = nil;
351
341
  }
352
- // Swift side should handle KVO observer removal for its tasks
353
342
  [super invalidate];
354
343
  }
355
344
 
@@ -520,14 +509,6 @@ RCT_EXPORT_MODULE();
520
509
  }
521
510
  }
522
511
 
523
- - (void)handleDownloadCompletion:(NSNotification *)notification {
524
- NSURLSessionTask *task = notification.object; // Task that finished
525
- RCTLogInfo(@"[HotUpdater.mm] Received download completion notification for task: %@", task.originalRequest.URL);
526
- // Swift side handles KVO observer removal internally now when task finishes.
527
- // No specific cleanup needed here based on this notification anymore.
528
- }
529
-
530
-
531
512
  #pragma mark - React Native Events (Keep as is)
532
513
 
533
514
  - (NSArray<NSString *> *)supportedEvents {
@@ -594,20 +575,17 @@ RCT_EXPORT_MODULE();
594
575
  if (params.bundleId()) {
595
576
  paramDict[@"bundleId"] = params.bundleId();
596
577
  }
597
- if (params.fileUrl()) {
598
- paramDict[@"fileUrl"] = params.fileUrl();
599
- }
600
- if (params.fileHash()) {
601
- paramDict[@"fileHash"] = params.fileHash();
602
- }
603
578
  if (params.manifestUrl()) {
604
579
  paramDict[@"manifestUrl"] = params.manifestUrl();
605
580
  }
606
581
  if (params.manifestFileHash()) {
607
582
  paramDict[@"manifestFileHash"] = params.manifestFileHash();
608
583
  }
609
- if (params.changedAssets()) {
610
- paramDict[@"changedAssets"] = params.changedAssets();
584
+ if (params.archiveUrl()) {
585
+ paramDict[@"archiveUrl"] = params.archiveUrl();
586
+ }
587
+ if (params.assets()) {
588
+ paramDict[@"assets"] = params.assets();
611
589
  }
612
590
  if (params.channel()) {
613
591
  paramDict[@"channel"] = params.channel();
@@ -682,19 +660,14 @@ RCT_EXPORT_MODULE();
682
660
  return [impl getInstallId];
683
661
  }
684
662
 
685
- - (NSString * _Nullable)getUserId {
686
- HotUpdaterImpl *impl = [HotUpdater sharedImpl];
687
- return [impl getUserId];
688
- }
689
-
690
- - (NSString * _Nullable)getUsername {
663
+ - (NSString * _Nullable)getStorageItem:(NSString *)key {
691
664
  HotUpdaterImpl *impl = [HotUpdater sharedImpl];
692
- return [impl getUsername];
665
+ return [impl getStorageItem:key];
693
666
  }
694
667
 
695
- - (void)setUser:(NSString * _Nullable)userId username:(NSString * _Nullable)username {
668
+ - (void)setStorageItem:(NSString *)key value:(NSString * _Nullable)value {
696
669
  HotUpdaterImpl *impl = [HotUpdater sharedImpl];
697
- [impl setUser:userId username:username];
670
+ [impl setStorageItem:key value:value];
698
671
  }
699
672
 
700
673
  - (NSString * _Nullable)getBaseURL {
@@ -852,19 +825,14 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getInstallId) {
852
825
  return [impl getInstallId];
853
826
  }
854
827
 
855
- RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getUserId) {
856
- HotUpdaterImpl *impl = [HotUpdater sharedImpl];
857
- return [impl getUserId];
858
- }
859
-
860
- RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getUsername) {
828
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getStorageItem:(NSString *)key) {
861
829
  HotUpdaterImpl *impl = [HotUpdater sharedImpl];
862
- return [impl getUsername];
830
+ return [impl getStorageItem:key];
863
831
  }
864
832
 
865
- RCT_EXPORT_METHOD(setUser:(NSString * _Nullable)userId username:(NSString * _Nullable)username) {
833
+ RCT_EXPORT_METHOD(setStorageItem:(NSString *)key value:(NSString * _Nullable)value) {
866
834
  HotUpdaterImpl *impl = [HotUpdater sharedImpl];
867
- [impl setUser:userId username:username];
835
+ [impl setStorageItem:key value:value];
868
836
  }
869
837
 
870
838
  RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getBaseURL) {