@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
@@ -1,132 +0,0 @@
1
- import type { ArtifactInfo, ReleaseCatalog } from "@hot-updater/core";
2
- import { beforeEach, describe, expect, it, vi } from "vitest";
3
-
4
- import { createHttpClient } from "./httpClient";
5
-
6
- const mocks = vi.hoisted(() => {
7
- Reflect.set(globalThis, "HotUpdater", {
8
- SDK_VERSION: "test-sdk-version",
9
- });
10
- return {
11
- fetchCatalog: vi.fn(),
12
- fetchJSON: vi.fn(),
13
- };
14
- });
15
-
16
- vi.mock("./releaseCatalogCache", () => ({
17
- fetchReleaseCatalogWithCache: mocks.fetchCatalog,
18
- }));
19
-
20
- vi.mock("./fetchJSON", () => ({
21
- fetchJSON: mocks.fetchJSON,
22
- }));
23
-
24
- const artifact: ArtifactInfo = {
25
- fileHash: "bundle-hash",
26
- fileUrl: "/storage/bundle.zip",
27
- };
28
-
29
- const catalog: ReleaseCatalog = {
30
- catalogId: "server-owned-project",
31
- catalogHash: `sha256:${"a".repeat(64)}`,
32
- fallbackPolicy: "BUILTIN_IF_ACTIVE_INELIGIBLE",
33
- generation: 1,
34
- releases: [],
35
- schemaVersion: 1,
36
- scopeKey: "v1:app-version:server-owned-project:ios:cHJvZHVjdGlvbg",
37
- };
38
-
39
- describe("private HotUpdater HTTP client", () => {
40
- beforeEach(() => {
41
- vi.clearAllMocks();
42
- mocks.fetchCatalog.mockResolvedValue(catalog);
43
- mocks.fetchJSON.mockResolvedValue(artifact);
44
- });
45
-
46
- it("fetches a catalog without putting its internal identity in the route", async () => {
47
- const session = await createHttpClient(
48
- "https://updates.example.com/hot-updater/",
49
- ).createSession();
50
-
51
- await expect(
52
- session.fetchReleaseCatalog({
53
- appVersion: "1.2.0",
54
- channel: "production",
55
- fingerprintHash: null,
56
- platform: "ios",
57
- updateStrategy: "appVersion",
58
- }),
59
- ).resolves.toBe(catalog);
60
-
61
- expect(mocks.fetchCatalog).toHaveBeenCalledWith({
62
- baseURL: "https://updates.example.com/hot-updater",
63
- expectedScope: {
64
- channelKey: "cHJvZHVjdGlvbg",
65
- platform: "ios",
66
- strategy: "APP_VERSION",
67
- },
68
- requestHeaders: undefined,
69
- requestTimeout: undefined,
70
- url: "https://updates.example.com/hot-updater/release-catalogs/app-version/ios/cHJvZHVjdGlvbg/1.2.0",
71
- });
72
- });
73
-
74
- it("resolves a functional baseURL once per session and captures it for a deferred artifact", async () => {
75
- const resolveBaseURL = vi
76
- .fn()
77
- .mockResolvedValueOnce("https://first.example.com/hot-updater")
78
- .mockResolvedValueOnce("https://second.example.com/hot-updater");
79
- const client = createHttpClient(resolveBaseURL);
80
- const firstSession = await client.createSession();
81
-
82
- await firstSession.fetchReleaseCatalog({
83
- appVersion: "1.2.0",
84
- channel: "production",
85
- fingerprintHash: null,
86
- platform: "ios",
87
- updateStrategy: "appVersion",
88
- });
89
- await expect(
90
- firstSession.resolveArtifact({
91
- currentBundleId: "current",
92
- targetBundleId: "target",
93
- }),
94
- ).resolves.toEqual({
95
- ...artifact,
96
- fileUrl: "https://first.example.com/hot-updater/storage/bundle.zip",
97
- });
98
-
99
- expect(resolveBaseURL).toHaveBeenCalledOnce();
100
- expect(mocks.fetchJSON).toHaveBeenCalledWith({
101
- requestHeaders: undefined,
102
- requestTimeout: undefined,
103
- url: "https://first.example.com/hot-updater/artifacts/target/from/current",
104
- });
105
-
106
- await client.createSession();
107
- expect(resolveBaseURL).toHaveBeenCalledTimes(2);
108
- });
109
-
110
- it("rejects non-storage relative artifact URLs", async () => {
111
- mocks.fetchJSON.mockResolvedValue({
112
- ...artifact,
113
- fileUrl: "/private/bundle.zip",
114
- });
115
- const session = await createHttpClient(
116
- "https://updates.example.com",
117
- ).createSession();
118
-
119
- await expect(
120
- session.resolveArtifact({
121
- currentBundleId: "current",
122
- targetBundleId: "target",
123
- }),
124
- ).rejects.toThrow("client-relative storage paths");
125
- });
126
-
127
- it("requires a functional baseURL to resolve to a non-empty string", async () => {
128
- await expect(createHttpClient(() => "").createSession()).rejects.toThrow(
129
- "baseURL function must return a non-empty string",
130
- );
131
- });
132
- });
package/src/index.spec.ts DELETED
@@ -1,337 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi } from "vitest";
2
-
3
- import type { HotUpdaterInitOptions, HotUpdaterOptions } from "./wrap";
4
-
5
- const mocks = vi.hoisted(() => {
6
- (
7
- globalThis as typeof globalThis & {
8
- HotUpdater: { SDK_VERSION: string };
9
- }
10
- ).HotUpdater = { SDK_VERSION: "test-sdk-version" };
11
-
12
- return {
13
- addListener: vi.fn(() => () => {}),
14
- checkForUpdate: vi.fn(async () => null),
15
- clearCrashHistory: vi.fn(() => true),
16
- createHttpClient: vi.fn((baseURL: unknown) => ({ baseURL })),
17
- getActiveUpdateState: vi.fn(() => ({
18
- activeSelection: null,
19
- highestSeenCatalogs: {},
20
- stableSelection: null,
21
- verificationPending: false,
22
- })),
23
- getAppVersion: vi.fn(() => "1.0.0"),
24
- getBaseURL: vi.fn(() => null),
25
- getUpdateId: vi.fn(() => "release-id"),
26
- getChannel: vi.fn(() => "production"),
27
- getCohort: vi.fn(() => "123"),
28
- getCrashHistory: vi.fn(() => []),
29
- getDefaultChannel: vi.fn(() => "production"),
30
- getFingerprintHash: vi.fn(() => null),
31
- getInstallId: vi.fn(() => "install-id"),
32
- getManifest: vi.fn(() => null),
33
- getMinBundleId: vi.fn(() => "min-bundle-id"),
34
- init: vi.fn(),
35
- isChannelSwitched: vi.fn(() => false),
36
- notifyAppReady: vi.fn(() => ({ status: "UNCHANGED" as const })),
37
- reload: vi.fn(),
38
- resetChannel: vi.fn(),
39
- setCohort: vi.fn(),
40
- setReloadBehavior: vi.fn(),
41
- setUser: vi.fn(),
42
- updateBundle: vi.fn(),
43
- wrap: vi.fn((Component: unknown) => Component),
44
- };
45
- });
46
-
47
- vi.mock("./httpClient", () => ({
48
- createHttpClient: mocks.createHttpClient,
49
- }));
50
-
51
- vi.mock("./checkForUpdate", () => ({
52
- checkForUpdate: mocks.checkForUpdate,
53
- }));
54
-
55
- vi.mock("./native", () => ({
56
- addListener: mocks.addListener,
57
- clearCrashHistory: mocks.clearCrashHistory,
58
- getPublicActiveUpdateState: mocks.getActiveUpdateState,
59
- getAppVersion: mocks.getAppVersion,
60
- getBaseURL: mocks.getBaseURL,
61
- getUpdateId: mocks.getUpdateId,
62
- getChannel: mocks.getChannel,
63
- getCohort: mocks.getCohort,
64
- getCrashHistory: mocks.getCrashHistory,
65
- getDefaultChannel: mocks.getDefaultChannel,
66
- getFingerprintHash: mocks.getFingerprintHash,
67
- getInstallId: mocks.getInstallId,
68
- getManifest: mocks.getManifest,
69
- getMinBundleId: mocks.getMinBundleId,
70
- isChannelSwitched: mocks.isChannelSwitched,
71
- notifyAppReady: mocks.notifyAppReady,
72
- reload: mocks.reload,
73
- resetChannel: mocks.resetChannel,
74
- setCohort: mocks.setCohort,
75
- setReloadBehavior: mocks.setReloadBehavior,
76
- setUser: mocks.setUser,
77
- updateBundle: mocks.updateBundle,
78
- }));
79
-
80
- vi.mock("./wrap", () => ({
81
- init: mocks.init,
82
- wrap: mocks.wrap,
83
- }));
84
-
85
- const importHotUpdater = async () => (await import("./index")).HotUpdater;
86
-
87
- describe("HotUpdater client initialization", () => {
88
- beforeEach(() => {
89
- vi.resetModules();
90
- vi.clearAllMocks();
91
- mocks.createHttpClient.mockImplementation((baseURL: unknown) => ({
92
- baseURL,
93
- }));
94
- mocks.checkForUpdate.mockResolvedValue(null);
95
- mocks.wrap.mockImplementation((Component: unknown) => Component);
96
- });
97
-
98
- it("exposes the console ID through the existing getter only", async () => {
99
- const HotUpdater = await importHotUpdater();
100
-
101
- expect(HotUpdater.getBundleId()).toBe("release-id");
102
- expect(HotUpdater).not.toHaveProperty("getReleaseId");
103
- expect(HotUpdater).not.toHaveProperty("getUpdateId");
104
- });
105
-
106
- it("initializes a private HTTP client from the required baseURL", async () => {
107
- const client = { createSession: vi.fn() };
108
- mocks.createHttpClient.mockReturnValue(client as never);
109
- const HotUpdater = await importHotUpdater();
110
-
111
- HotUpdater.init({
112
- insights: true,
113
- baseURL: "https://updates.example.com",
114
- requestHeaders: { Authorization: "Bearer token" },
115
- requestTimeout: 1000,
116
- });
117
-
118
- expect(mocks.createHttpClient).toHaveBeenCalledWith(
119
- "https://updates.example.com",
120
- );
121
- expect(mocks.init).toHaveBeenCalledWith({
122
- insights: true,
123
- client,
124
- requestHeaders: { Authorization: "Bearer token" },
125
- requestTimeout: 1000,
126
- });
127
- });
128
-
129
- it("accepts a functional baseURL without resolving it during init", async () => {
130
- const resolveBaseURL = vi.fn(() => "https://updates.example.com");
131
- const HotUpdater = await importHotUpdater();
132
-
133
- HotUpdater.init({ baseURL: resolveBaseURL });
134
-
135
- expect(mocks.createHttpClient).toHaveBeenCalledWith(resolveBaseURL);
136
- expect(resolveBaseURL).not.toHaveBeenCalled();
137
- });
138
-
139
- it("enables insights by default for init and wrap", async () => {
140
- const HotUpdater = await importHotUpdater();
141
-
142
- HotUpdater.init({ baseURL: "https://updates.example.com" });
143
- HotUpdater.wrap({
144
- baseURL: "https://updates.example.com",
145
- updateStrategy: "appVersion",
146
- });
147
-
148
- expect(mocks.init).toHaveBeenCalledWith(
149
- expect.objectContaining({ insights: true }),
150
- );
151
- expect(mocks.wrap).toHaveBeenCalledWith(
152
- expect.objectContaining({ insights: true }),
153
- );
154
- });
155
-
156
- it("preserves an explicit insights opt-out", async () => {
157
- const HotUpdater = await importHotUpdater();
158
-
159
- HotUpdater.init({
160
- baseURL: "https://updates.example.com",
161
- insights: false,
162
- });
163
- HotUpdater.wrap({
164
- baseURL: "https://updates.example.com",
165
- insights: false,
166
- updateStrategy: "appVersion",
167
- });
168
-
169
- expect(mocks.init).toHaveBeenCalledWith(
170
- expect.objectContaining({ insights: false }),
171
- );
172
- expect(mocks.wrap).toHaveBeenCalledWith(
173
- expect.objectContaining({ insights: false }),
174
- );
175
- });
176
-
177
- it("requires baseURL and rejects the removed resolver shape", async () => {
178
- const HotUpdater = await importHotUpdater();
179
-
180
- expect(() => HotUpdater.init({} as never)).toThrow(
181
- "baseURL must be provided",
182
- );
183
- expect(() => HotUpdater.init({ resolver: {} } as never)).toThrow(
184
- "baseURL must be provided",
185
- );
186
- expect(mocks.init).not.toHaveBeenCalled();
187
- });
188
-
189
- it("types init and wrap with baseURL but no resolver or catalogId", () => {
190
- const initOptions = {
191
- baseURL: "https://updates.example.com",
192
- } satisfies HotUpdaterInitOptions;
193
- const wrapOptions = {
194
- baseURL: async () => "https://updates.example.com",
195
- updateStrategy: "appVersion",
196
- } satisfies HotUpdaterOptions;
197
-
198
- const assertRemovedInputsStayRejected = () => {
199
- // @ts-expect-error baseURL is required
200
- const missingBaseURL: HotUpdaterInitOptions = {};
201
- // @ts-expect-error resolver is no longer a public input
202
- const customResolver: HotUpdaterInitOptions = { resolver: {} };
203
- const clientCatalog: HotUpdaterInitOptions = {
204
- // @ts-expect-error catalogId is internal protocol metadata
205
- catalogId: "project-a",
206
- baseURL: "https://updates.example.com",
207
- };
208
- void missingBaseURL;
209
- void customResolver;
210
- void clientCatalog;
211
- };
212
-
213
- expect(assertRemovedInputsStayRejected).toBeTypeOf("function");
214
- expect(initOptions.baseURL).toBe("https://updates.example.com");
215
- expect(wrapOptions.updateStrategy).toBe("appVersion");
216
- });
217
-
218
- it("merges settings and carries the insights gate to checks", async () => {
219
- const client = { createSession: vi.fn() };
220
- mocks.createHttpClient.mockReturnValue(client as never);
221
- const checkOnError = vi.fn();
222
- const HotUpdater = await importHotUpdater();
223
- HotUpdater.init({
224
- insights: true,
225
- baseURL: "https://updates.example.com",
226
- requestHeaders: { Authorization: "Bearer token" },
227
- requestTimeout: 1000,
228
- });
229
-
230
- await HotUpdater.checkForUpdate({
231
- onError: checkOnError,
232
- requestHeaders: { "X-Runtime": "secondary" },
233
- updateStrategy: "appVersion",
234
- });
235
-
236
- expect(mocks.checkForUpdate).toHaveBeenCalledWith({
237
- insights: true,
238
- client,
239
- onError: checkOnError,
240
- requestHeaders: {
241
- Authorization: "Bearer token",
242
- "X-Runtime": "secondary",
243
- },
244
- requestTimeout: 1000,
245
- updateStrategy: "appVersion",
246
- });
247
- });
248
-
249
- it("normalizes wrap with the same private client contract", async () => {
250
- const client = { createSession: vi.fn() };
251
- mocks.createHttpClient.mockReturnValue(client as never);
252
- const HotUpdater = await importHotUpdater();
253
-
254
- HotUpdater.wrap({
255
- insights: true,
256
- baseURL: "https://updates.example.com",
257
- updateStrategy: "appVersion",
258
- });
259
-
260
- expect(mocks.wrap).toHaveBeenCalledWith({
261
- insights: true,
262
- client,
263
- updateStrategy: "appVersion",
264
- });
265
- });
266
-
267
- it.each([
268
- ["init", "wrap"],
269
- ["wrap", "init"],
270
- ] as const)(
271
- "reports %s and %s mixed usage exactly once",
272
- async (first, second) => {
273
- const consoleError = vi
274
- .spyOn(console, "error")
275
- .mockImplementation(() => undefined);
276
- const HotUpdater = await importHotUpdater();
277
- const configure = (api: "init" | "wrap") => {
278
- if (api === "init") {
279
- HotUpdater.init({ baseURL: "https://updates.example.com" });
280
- return;
281
- }
282
- HotUpdater.wrap({
283
- baseURL: "https://updates.example.com",
284
- updateStrategy: "appVersion",
285
- });
286
- };
287
-
288
- configure(first);
289
- configure(second);
290
- configure(second);
291
-
292
- expect(consoleError).toHaveBeenCalledOnce();
293
- expect(consoleError).toHaveBeenCalledWith(
294
- expect.stringContaining(
295
- "HotUpdater.init() and HotUpdater.wrap() must not be used together",
296
- ),
297
- );
298
- expect(consoleError).toHaveBeenCalledWith(
299
- expect.stringContaining(
300
- "use HotUpdater.init() with HotUpdater.checkForUpdate()",
301
- ),
302
- );
303
- consoleError.mockRestore();
304
- },
305
- );
306
-
307
- it("rejects removed manual wrap options", async () => {
308
- const HotUpdater = await importHotUpdater();
309
-
310
- expect(() =>
311
- HotUpdater.wrap({
312
- baseURL: "https://updates.example.com",
313
- updateMode: "manual",
314
- } as never),
315
- ).toThrow('HotUpdater.wrap({ updateMode: "manual" }) was removed');
316
- });
317
-
318
- it("requires initialization before manual update APIs", async () => {
319
- const HotUpdater = await importHotUpdater();
320
-
321
- expect(() =>
322
- HotUpdater.checkForUpdate({ updateStrategy: "appVersion" }),
323
- ).toThrow("requires HotUpdater.wrap() or HotUpdater.init() to be used");
324
- });
325
-
326
- it("preserves native identity and user APIs", async () => {
327
- const HotUpdater = await importHotUpdater();
328
-
329
- expect(HotUpdater.getInstallId()).toBe("install-id");
330
- expect(HotUpdater.getMinBundleId()).toBe("min-bundle-id");
331
- HotUpdater.setUser({ userId: "user-123", username: "alice" });
332
- expect(mocks.setUser).toHaveBeenCalledWith({
333
- userId: "user-123",
334
- username: "alice",
335
- });
336
- });
337
- });
@@ -1,30 +0,0 @@
1
- import { readFileSync } from "node:fs";
2
- import { resolve } from "node:path";
3
-
4
- import { describe, expect, it } from "vitest";
5
-
6
- const iosInternalDirectory = resolve(
7
- import.meta.dirname,
8
- "../ios/HotUpdater/Internal",
9
- );
10
-
11
- const readIOSSource = (filename: string) =>
12
- readFileSync(resolve(iosInternalDirectory, filename), "utf8");
13
-
14
- describe("iOS Objective-C interoperability", () => {
15
- it("does not call an autoreleased NSString through raw Swift ABI", () => {
16
- const implementation = readIOSSource("HotUpdaterImpl.swift");
17
- const objectiveCImplementation = readIOSSource("HotUpdater.mm");
18
-
19
- expect(implementation).not.toContain(
20
- '@_silgen_name("HotUpdaterGetMinBundleId")',
21
- );
22
- expect(implementation).toContain(
23
- '@_silgen_name("HotUpdaterCopyMinBundleId")',
24
- );
25
- expect(implementation).toContain(".takeRetainedValue() as String");
26
- expect(objectiveCImplementation).toContain(
27
- "return (__bridge_retained void *)HotUpdaterGetMinBundleId();",
28
- );
29
- });
30
- });