@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
@@ -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,331 +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
- getBundleId: vi.fn(() => "bundle-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
- getReleaseId: vi.fn(async () => null),
35
- init: vi.fn(),
36
- isChannelSwitched: vi.fn(() => false),
37
- notifyAppReady: vi.fn(() => ({ status: "UNCHANGED" as const })),
38
- reload: vi.fn(),
39
- resetChannel: vi.fn(),
40
- setCohort: vi.fn(),
41
- setReloadBehavior: vi.fn(),
42
- setUser: vi.fn(),
43
- updateBundle: vi.fn(),
44
- wrap: vi.fn((Component: unknown) => Component),
45
- };
46
- });
47
-
48
- vi.mock("./httpClient", () => ({
49
- createHttpClient: mocks.createHttpClient,
50
- }));
51
-
52
- vi.mock("./checkForUpdate", () => ({
53
- checkForUpdate: mocks.checkForUpdate,
54
- }));
55
-
56
- vi.mock("./native", () => ({
57
- addListener: mocks.addListener,
58
- clearCrashHistory: mocks.clearCrashHistory,
59
- getPublicActiveUpdateState: mocks.getActiveUpdateState,
60
- getAppVersion: mocks.getAppVersion,
61
- getBaseURL: mocks.getBaseURL,
62
- getBundleId: mocks.getBundleId,
63
- getChannel: mocks.getChannel,
64
- getCohort: mocks.getCohort,
65
- getCrashHistory: mocks.getCrashHistory,
66
- getDefaultChannel: mocks.getDefaultChannel,
67
- getFingerprintHash: mocks.getFingerprintHash,
68
- getInstallId: mocks.getInstallId,
69
- getManifest: mocks.getManifest,
70
- getMinBundleId: mocks.getMinBundleId,
71
- getReleaseId: mocks.getReleaseId,
72
- isChannelSwitched: mocks.isChannelSwitched,
73
- notifyAppReady: mocks.notifyAppReady,
74
- reload: mocks.reload,
75
- resetChannel: mocks.resetChannel,
76
- setCohort: mocks.setCohort,
77
- setReloadBehavior: mocks.setReloadBehavior,
78
- setUser: mocks.setUser,
79
- updateBundle: mocks.updateBundle,
80
- }));
81
-
82
- vi.mock("./wrap", () => ({
83
- init: mocks.init,
84
- wrap: mocks.wrap,
85
- }));
86
-
87
- const importHotUpdater = async () => (await import("./index")).HotUpdater;
88
-
89
- describe("HotUpdater client initialization", () => {
90
- beforeEach(() => {
91
- vi.resetModules();
92
- vi.clearAllMocks();
93
- mocks.createHttpClient.mockImplementation((baseURL: unknown) => ({
94
- baseURL,
95
- }));
96
- mocks.checkForUpdate.mockResolvedValue(null);
97
- mocks.wrap.mockImplementation((Component: unknown) => Component);
98
- });
99
-
100
- it("initializes a private HTTP client from the required baseURL", async () => {
101
- const client = { createSession: vi.fn() };
102
- mocks.createHttpClient.mockReturnValue(client as never);
103
- const HotUpdater = await importHotUpdater();
104
-
105
- HotUpdater.init({
106
- insights: true,
107
- baseURL: "https://updates.example.com",
108
- requestHeaders: { Authorization: "Bearer token" },
109
- requestTimeout: 1000,
110
- });
111
-
112
- expect(mocks.createHttpClient).toHaveBeenCalledWith(
113
- "https://updates.example.com",
114
- );
115
- expect(mocks.init).toHaveBeenCalledWith({
116
- insights: true,
117
- client,
118
- requestHeaders: { Authorization: "Bearer token" },
119
- requestTimeout: 1000,
120
- });
121
- });
122
-
123
- it("accepts a functional baseURL without resolving it during init", async () => {
124
- const resolveBaseURL = vi.fn(() => "https://updates.example.com");
125
- const HotUpdater = await importHotUpdater();
126
-
127
- HotUpdater.init({ baseURL: resolveBaseURL });
128
-
129
- expect(mocks.createHttpClient).toHaveBeenCalledWith(resolveBaseURL);
130
- expect(resolveBaseURL).not.toHaveBeenCalled();
131
- });
132
-
133
- it("enables insights by default for init and wrap", async () => {
134
- const HotUpdater = await importHotUpdater();
135
-
136
- HotUpdater.init({ baseURL: "https://updates.example.com" });
137
- HotUpdater.wrap({
138
- baseURL: "https://updates.example.com",
139
- updateStrategy: "appVersion",
140
- });
141
-
142
- expect(mocks.init).toHaveBeenCalledWith(
143
- expect.objectContaining({ insights: true }),
144
- );
145
- expect(mocks.wrap).toHaveBeenCalledWith(
146
- expect.objectContaining({ insights: true }),
147
- );
148
- });
149
-
150
- it("preserves an explicit insights opt-out", async () => {
151
- const HotUpdater = await importHotUpdater();
152
-
153
- HotUpdater.init({
154
- baseURL: "https://updates.example.com",
155
- insights: false,
156
- });
157
- HotUpdater.wrap({
158
- baseURL: "https://updates.example.com",
159
- insights: false,
160
- updateStrategy: "appVersion",
161
- });
162
-
163
- expect(mocks.init).toHaveBeenCalledWith(
164
- expect.objectContaining({ insights: false }),
165
- );
166
- expect(mocks.wrap).toHaveBeenCalledWith(
167
- expect.objectContaining({ insights: false }),
168
- );
169
- });
170
-
171
- it("requires baseURL and rejects the removed resolver shape", async () => {
172
- const HotUpdater = await importHotUpdater();
173
-
174
- expect(() => HotUpdater.init({} as never)).toThrow(
175
- "baseURL must be provided",
176
- );
177
- expect(() => HotUpdater.init({ resolver: {} } as never)).toThrow(
178
- "baseURL must be provided",
179
- );
180
- expect(mocks.init).not.toHaveBeenCalled();
181
- });
182
-
183
- it("types init and wrap with baseURL but no resolver or catalogId", () => {
184
- const initOptions = {
185
- baseURL: "https://updates.example.com",
186
- } satisfies HotUpdaterInitOptions;
187
- const wrapOptions = {
188
- baseURL: async () => "https://updates.example.com",
189
- updateStrategy: "appVersion",
190
- } satisfies HotUpdaterOptions;
191
-
192
- const assertRemovedInputsStayRejected = () => {
193
- // @ts-expect-error baseURL is required
194
- const missingBaseURL: HotUpdaterInitOptions = {};
195
- // @ts-expect-error resolver is no longer a public input
196
- const customResolver: HotUpdaterInitOptions = { resolver: {} };
197
- const clientCatalog: HotUpdaterInitOptions = {
198
- // @ts-expect-error catalogId is internal protocol metadata
199
- catalogId: "project-a",
200
- baseURL: "https://updates.example.com",
201
- };
202
- void missingBaseURL;
203
- void customResolver;
204
- void clientCatalog;
205
- };
206
-
207
- expect(assertRemovedInputsStayRejected).toBeTypeOf("function");
208
- expect(initOptions.baseURL).toBe("https://updates.example.com");
209
- expect(wrapOptions.updateStrategy).toBe("appVersion");
210
- });
211
-
212
- it("merges settings and carries the insights gate to checks", async () => {
213
- const client = { createSession: vi.fn() };
214
- mocks.createHttpClient.mockReturnValue(client as never);
215
- const checkOnError = vi.fn();
216
- const HotUpdater = await importHotUpdater();
217
- HotUpdater.init({
218
- insights: true,
219
- baseURL: "https://updates.example.com",
220
- requestHeaders: { Authorization: "Bearer token" },
221
- requestTimeout: 1000,
222
- });
223
-
224
- await HotUpdater.checkForUpdate({
225
- onError: checkOnError,
226
- requestHeaders: { "X-Runtime": "secondary" },
227
- updateStrategy: "appVersion",
228
- });
229
-
230
- expect(mocks.checkForUpdate).toHaveBeenCalledWith({
231
- insights: true,
232
- client,
233
- onError: checkOnError,
234
- requestHeaders: {
235
- Authorization: "Bearer token",
236
- "X-Runtime": "secondary",
237
- },
238
- requestTimeout: 1000,
239
- updateStrategy: "appVersion",
240
- });
241
- });
242
-
243
- it("normalizes wrap with the same private client contract", async () => {
244
- const client = { createSession: vi.fn() };
245
- mocks.createHttpClient.mockReturnValue(client as never);
246
- const HotUpdater = await importHotUpdater();
247
-
248
- HotUpdater.wrap({
249
- insights: true,
250
- baseURL: "https://updates.example.com",
251
- updateStrategy: "appVersion",
252
- });
253
-
254
- expect(mocks.wrap).toHaveBeenCalledWith({
255
- insights: true,
256
- client,
257
- updateStrategy: "appVersion",
258
- });
259
- });
260
-
261
- it.each([
262
- ["init", "wrap"],
263
- ["wrap", "init"],
264
- ] as const)(
265
- "reports %s and %s mixed usage exactly once",
266
- async (first, second) => {
267
- const consoleError = vi
268
- .spyOn(console, "error")
269
- .mockImplementation(() => undefined);
270
- const HotUpdater = await importHotUpdater();
271
- const configure = (api: "init" | "wrap") => {
272
- if (api === "init") {
273
- HotUpdater.init({ baseURL: "https://updates.example.com" });
274
- return;
275
- }
276
- HotUpdater.wrap({
277
- baseURL: "https://updates.example.com",
278
- updateStrategy: "appVersion",
279
- });
280
- };
281
-
282
- configure(first);
283
- configure(second);
284
- configure(second);
285
-
286
- expect(consoleError).toHaveBeenCalledOnce();
287
- expect(consoleError).toHaveBeenCalledWith(
288
- expect.stringContaining(
289
- "HotUpdater.init() and HotUpdater.wrap() must not be used together",
290
- ),
291
- );
292
- expect(consoleError).toHaveBeenCalledWith(
293
- expect.stringContaining(
294
- "use HotUpdater.init() with HotUpdater.checkForUpdate()",
295
- ),
296
- );
297
- consoleError.mockRestore();
298
- },
299
- );
300
-
301
- it("rejects removed manual wrap options", async () => {
302
- const HotUpdater = await importHotUpdater();
303
-
304
- expect(() =>
305
- HotUpdater.wrap({
306
- baseURL: "https://updates.example.com",
307
- updateMode: "manual",
308
- } as never),
309
- ).toThrow('HotUpdater.wrap({ updateMode: "manual" }) was removed');
310
- });
311
-
312
- it("requires initialization before manual update APIs", async () => {
313
- const HotUpdater = await importHotUpdater();
314
-
315
- expect(() =>
316
- HotUpdater.checkForUpdate({ updateStrategy: "appVersion" }),
317
- ).toThrow("requires HotUpdater.wrap() or HotUpdater.init() to be used");
318
- });
319
-
320
- it("preserves native identity and user APIs", async () => {
321
- const HotUpdater = await importHotUpdater();
322
-
323
- expect(HotUpdater.getInstallId()).toBe("install-id");
324
- expect(HotUpdater.getMinBundleId()).toBe("min-bundle-id");
325
- HotUpdater.setUser({ userId: "user-123", username: "alice" });
326
- expect(mocks.setUser).toHaveBeenCalledWith({
327
- userId: "user-123",
328
- username: "alice",
329
- });
330
- });
331
- });
@@ -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
- });