@hot-updater/react-native 0.36.6 → 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/android/src/main/java/com/hotupdater/BundleFileStorageService.kt +357 -6
  2. package/android/src/main/java/com/hotupdater/BundleMetadata.kt +268 -34
  3. package/android/src/main/java/com/hotupdater/HotUpdaterImpl.kt +75 -9
  4. package/android/src/main/java/com/hotupdater/NativeConfigUtils.kt +2 -16
  5. package/android/src/main/java/com/hotupdater/ReleaseCatalogCacheService.kt +166 -0
  6. package/android/src/main/java/com/hotupdater/SignatureVerifier.kt +1 -2
  7. package/android/src/newarch/HotUpdater.kt +1 -1
  8. package/android/src/newarch/HotUpdaterModule.kt +116 -0
  9. package/android/src/oldarch/HotUpdater.kt +1 -1
  10. package/android/src/oldarch/HotUpdaterModule.kt +128 -0
  11. package/android/src/oldarch/HotUpdaterSpec.kt +38 -0
  12. package/android/src/test/java/com/hotupdater/BundleFileStorageServiceTest.kt +280 -2
  13. package/android/src/test/java/com/hotupdater/HotUpdaterImplTest.kt +57 -2
  14. package/android/src/test/java/com/hotupdater/ReleaseCatalogCacheServiceTest.kt +118 -0
  15. package/ios/HotUpdater/Internal/BundleFileStorageService.swift +491 -30
  16. package/ios/HotUpdater/Internal/BundleMetadata.swift +229 -6
  17. package/ios/HotUpdater/Internal/HotUpdater.mm +122 -0
  18. package/ios/HotUpdater/Internal/HotUpdaterImpl.swift +176 -7
  19. package/ios/HotUpdater/Internal/ReleaseCatalogCacheService.swift +213 -0
  20. package/lib/commonjs/catalogCacheNative.js +44 -0
  21. package/lib/commonjs/catalogCacheNative.js.map +1 -0
  22. package/lib/commonjs/catalogCacheNative.spec.js +31 -0
  23. package/lib/commonjs/catalogCacheNative.spec.js.map +1 -0
  24. package/lib/commonjs/checkForUpdate.js +231 -60
  25. package/lib/commonjs/checkForUpdate.js.map +1 -1
  26. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js +604 -0
  27. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js.map +1 -0
  28. package/lib/commonjs/error.js +8 -1
  29. package/lib/commonjs/error.js.map +1 -1
  30. package/lib/commonjs/{fetchUpdateInfo.js → fetchJSON.js} +11 -14
  31. package/lib/commonjs/fetchJSON.js.map +1 -0
  32. package/lib/commonjs/httpClient.js +153 -0
  33. package/lib/commonjs/httpClient.js.map +1 -0
  34. package/lib/commonjs/httpClient.spec.js +102 -0
  35. package/lib/commonjs/httpClient.spec.js.map +1 -0
  36. package/lib/commonjs/index.js +48 -71
  37. package/lib/commonjs/index.js.map +1 -1
  38. package/lib/commonjs/index.spec.js +117 -161
  39. package/lib/commonjs/index.spec.js.map +1 -1
  40. package/lib/commonjs/iosInterop.spec.js +18 -0
  41. package/lib/commonjs/iosInterop.spec.js.map +1 -0
  42. package/lib/commonjs/native.js +222 -55
  43. package/lib/commonjs/native.js.map +1 -1
  44. package/lib/commonjs/native.spec.js +226 -12
  45. package/lib/commonjs/native.spec.js.map +1 -1
  46. package/lib/commonjs/notifyAppReadyAnalytics.boundary.spec.js +218 -0
  47. package/lib/commonjs/notifyAppReadyAnalytics.boundary.spec.js.map +1 -0
  48. package/lib/commonjs/notifyAppReadyAnalytics.js +133 -0
  49. package/lib/commonjs/notifyAppReadyAnalytics.js.map +1 -0
  50. package/lib/commonjs/notifyAppReadyAnalytics.spec.js +246 -0
  51. package/lib/commonjs/notifyAppReadyAnalytics.spec.js.map +1 -0
  52. package/lib/commonjs/notifyAppReadyAnalytics.test-utils.js +24 -0
  53. package/lib/commonjs/notifyAppReadyAnalytics.test-utils.js.map +1 -0
  54. package/lib/commonjs/notifyAppReadyAnalytics.transport.spec.js +117 -0
  55. package/lib/commonjs/notifyAppReadyAnalytics.transport.spec.js.map +1 -0
  56. package/lib/commonjs/releaseCatalogCache.js +179 -0
  57. package/lib/commonjs/releaseCatalogCache.js.map +1 -0
  58. package/lib/commonjs/releaseCatalogCache.spec.js +195 -0
  59. package/lib/commonjs/releaseCatalogCache.spec.js.map +1 -0
  60. package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js +64 -0
  61. package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js.map +1 -0
  62. package/lib/commonjs/sdkVersion.js +1 -1
  63. package/lib/commonjs/sdkVersion.js.map +1 -1
  64. package/lib/commonjs/specs/NativeHotUpdater.js.map +1 -1
  65. package/lib/commonjs/types.js +0 -12
  66. package/lib/commonjs/types.js.map +1 -1
  67. package/lib/commonjs/wrap.js +7 -82
  68. package/lib/commonjs/wrap.js.map +1 -1
  69. package/lib/commonjs/wrap.spec.js +203 -56
  70. package/lib/commonjs/wrap.spec.js.map +1 -1
  71. package/lib/commonjs/wrap.types.js +6 -0
  72. package/lib/commonjs/wrap.types.js.map +1 -0
  73. package/lib/module/catalogCacheNative.js +36 -0
  74. package/lib/module/catalogCacheNative.js.map +1 -0
  75. package/lib/module/catalogCacheNative.spec.js +31 -0
  76. package/lib/module/catalogCacheNative.spec.js.map +1 -0
  77. package/lib/module/checkForUpdate.js +233 -62
  78. package/lib/module/checkForUpdate.js.map +1 -1
  79. package/lib/module/checkForUpdate.releaseCatalog.spec.js +603 -0
  80. package/lib/module/checkForUpdate.releaseCatalog.spec.js.map +1 -0
  81. package/lib/module/error.js +6 -0
  82. package/lib/module/error.js.map +1 -1
  83. package/lib/module/{fetchUpdateInfo.js → fetchJSON.js} +9 -12
  84. package/lib/module/fetchJSON.js.map +1 -0
  85. package/lib/module/httpClient.js +148 -0
  86. package/lib/module/httpClient.js.map +1 -0
  87. package/lib/module/httpClient.spec.js +102 -0
  88. package/lib/module/httpClient.spec.js.map +1 -0
  89. package/lib/module/index.js +49 -66
  90. package/lib/module/index.js.map +1 -1
  91. package/lib/module/index.spec.js +117 -161
  92. package/lib/module/index.spec.js.map +1 -1
  93. package/lib/module/iosInterop.spec.js +18 -0
  94. package/lib/module/iosInterop.spec.js.map +1 -0
  95. package/lib/module/native.js +206 -51
  96. package/lib/module/native.js.map +1 -1
  97. package/lib/module/native.spec.js +226 -12
  98. package/lib/module/native.spec.js.map +1 -1
  99. package/lib/module/notifyAppReadyAnalytics.boundary.spec.js +217 -0
  100. package/lib/module/notifyAppReadyAnalytics.boundary.spec.js.map +1 -0
  101. package/lib/module/notifyAppReadyAnalytics.js +128 -0
  102. package/lib/module/notifyAppReadyAnalytics.js.map +1 -0
  103. package/lib/module/notifyAppReadyAnalytics.spec.js +245 -0
  104. package/lib/module/notifyAppReadyAnalytics.spec.js.map +1 -0
  105. package/lib/module/notifyAppReadyAnalytics.test-utils.js +18 -0
  106. package/lib/module/notifyAppReadyAnalytics.test-utils.js.map +1 -0
  107. package/lib/module/notifyAppReadyAnalytics.transport.spec.js +116 -0
  108. package/lib/module/notifyAppReadyAnalytics.transport.spec.js.map +1 -0
  109. package/lib/module/releaseCatalogCache.js +171 -0
  110. package/lib/module/releaseCatalogCache.js.map +1 -0
  111. package/lib/module/releaseCatalogCache.spec.js +195 -0
  112. package/lib/module/releaseCatalogCache.spec.js.map +1 -0
  113. package/lib/module/releaseCatalogCacheNativeContract.spec.js +64 -0
  114. package/lib/module/releaseCatalogCacheNativeContract.spec.js.map +1 -0
  115. package/lib/module/sdkVersion.js +1 -1
  116. package/lib/module/sdkVersion.js.map +1 -1
  117. package/lib/module/specs/NativeHotUpdater.js.map +1 -1
  118. package/lib/module/types.js +0 -12
  119. package/lib/module/types.js.map +1 -1
  120. package/lib/module/wrap.js +6 -81
  121. package/lib/module/wrap.js.map +1 -1
  122. package/lib/module/wrap.spec.js +203 -56
  123. package/lib/module/wrap.spec.js.map +1 -1
  124. package/lib/module/wrap.types.js +4 -0
  125. package/lib/module/wrap.types.js.map +1 -0
  126. package/lib/typescript/commonjs/catalogCacheNative.d.ts +4 -0
  127. package/lib/typescript/commonjs/catalogCacheNative.d.ts.map +1 -0
  128. package/lib/typescript/commonjs/checkForUpdate.d.ts +14 -4
  129. package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
  130. package/lib/typescript/commonjs/error.d.ts +3 -0
  131. package/lib/typescript/commonjs/error.d.ts.map +1 -1
  132. package/lib/typescript/commonjs/fetchJSON.d.ts +6 -0
  133. package/lib/typescript/commonjs/fetchJSON.d.ts.map +1 -0
  134. package/lib/typescript/commonjs/httpClient.d.ts +56 -0
  135. package/lib/typescript/commonjs/httpClient.d.ts.map +1 -0
  136. package/lib/typescript/commonjs/index.d.ts +32 -41
  137. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  138. package/lib/typescript/commonjs/native.d.ts +83 -18
  139. package/lib/typescript/commonjs/native.d.ts.map +1 -1
  140. package/lib/typescript/commonjs/notifyAppReadyAnalytics.d.ts +13 -0
  141. package/lib/typescript/commonjs/notifyAppReadyAnalytics.d.ts.map +1 -0
  142. package/lib/typescript/commonjs/notifyAppReadyAnalytics.test-utils.d.ts +8 -0
  143. package/lib/typescript/commonjs/notifyAppReadyAnalytics.test-utils.d.ts.map +1 -0
  144. package/lib/typescript/commonjs/releaseCatalogCache.d.ts +25 -0
  145. package/lib/typescript/commonjs/releaseCatalogCache.d.ts.map +1 -0
  146. package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
  147. package/lib/typescript/commonjs/sdkVersion.d.ts.map +1 -1
  148. package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts +40 -5
  149. package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts.map +1 -1
  150. package/lib/typescript/commonjs/types.d.ts +0 -118
  151. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  152. package/lib/typescript/commonjs/wrap.d.ts +2 -191
  153. package/lib/typescript/commonjs/wrap.d.ts.map +1 -1
  154. package/lib/typescript/commonjs/wrap.types.d.ts +65 -0
  155. package/lib/typescript/commonjs/wrap.types.d.ts.map +1 -0
  156. package/lib/typescript/module/catalogCacheNative.d.ts +4 -0
  157. package/lib/typescript/module/catalogCacheNative.d.ts.map +1 -0
  158. package/lib/typescript/module/checkForUpdate.d.ts +14 -4
  159. package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
  160. package/lib/typescript/module/error.d.ts +3 -0
  161. package/lib/typescript/module/error.d.ts.map +1 -1
  162. package/lib/typescript/module/fetchJSON.d.ts +6 -0
  163. package/lib/typescript/module/fetchJSON.d.ts.map +1 -0
  164. package/lib/typescript/module/httpClient.d.ts +56 -0
  165. package/lib/typescript/module/httpClient.d.ts.map +1 -0
  166. package/lib/typescript/module/index.d.ts +32 -41
  167. package/lib/typescript/module/index.d.ts.map +1 -1
  168. package/lib/typescript/module/native.d.ts +83 -18
  169. package/lib/typescript/module/native.d.ts.map +1 -1
  170. package/lib/typescript/module/notifyAppReadyAnalytics.d.ts +13 -0
  171. package/lib/typescript/module/notifyAppReadyAnalytics.d.ts.map +1 -0
  172. package/lib/typescript/module/notifyAppReadyAnalytics.test-utils.d.ts +8 -0
  173. package/lib/typescript/module/notifyAppReadyAnalytics.test-utils.d.ts.map +1 -0
  174. package/lib/typescript/module/releaseCatalogCache.d.ts +25 -0
  175. package/lib/typescript/module/releaseCatalogCache.d.ts.map +1 -0
  176. package/lib/typescript/module/sdkVersion.d.ts +1 -1
  177. package/lib/typescript/module/sdkVersion.d.ts.map +1 -1
  178. package/lib/typescript/module/specs/NativeHotUpdater.d.ts +40 -5
  179. package/lib/typescript/module/specs/NativeHotUpdater.d.ts.map +1 -1
  180. package/lib/typescript/module/types.d.ts +0 -118
  181. package/lib/typescript/module/types.d.ts.map +1 -1
  182. package/lib/typescript/module/wrap.d.ts +2 -191
  183. package/lib/typescript/module/wrap.d.ts.map +1 -1
  184. package/lib/typescript/module/wrap.types.d.ts +65 -0
  185. package/lib/typescript/module/wrap.types.d.ts.map +1 -0
  186. package/package.json +6 -24
  187. package/src/catalogCacheNative.spec.ts +63 -0
  188. package/src/catalogCacheNative.ts +74 -0
  189. package/src/checkForUpdate.releaseCatalog.spec.ts +596 -0
  190. package/src/checkForUpdate.ts +368 -97
  191. package/src/error.ts +7 -0
  192. package/src/{fetchUpdateInfo.ts → fetchJSON.ts} +8 -15
  193. package/src/httpClient.spec.ts +132 -0
  194. package/src/httpClient.ts +261 -0
  195. package/src/index.spec.ts +110 -203
  196. package/src/index.ts +70 -93
  197. package/src/iosInterop.spec.ts +30 -0
  198. package/src/native.spec.ts +226 -10
  199. package/src/native.ts +385 -83
  200. package/src/notifyAppReadyAnalytics.boundary.spec.ts +234 -0
  201. package/src/notifyAppReadyAnalytics.spec.ts +243 -0
  202. package/src/notifyAppReadyAnalytics.test-utils.ts +31 -0
  203. package/src/notifyAppReadyAnalytics.transport.spec.ts +130 -0
  204. package/src/notifyAppReadyAnalytics.ts +194 -0
  205. package/src/releaseCatalogCache.spec.ts +282 -0
  206. package/src/releaseCatalogCache.ts +341 -0
  207. package/src/releaseCatalogCacheNativeContract.spec.ts +80 -0
  208. package/src/sdkVersion.ts +1 -1
  209. package/src/specs/NativeHotUpdater.ts +51 -5
  210. package/src/types.ts +0 -140
  211. package/src/wrap.spec.ts +251 -56
  212. package/src/wrap.tsx +23 -318
  213. package/src/wrap.types.ts +78 -0
  214. package/android/src/main/java/com/hotupdater/StringResourceUtils.kt +0 -45
  215. package/app.plugin.js +0 -1
  216. package/ios/HotUpdater/Internal/HotUpdaterCrashHandler.h +0 -7
  217. package/ios/HotUpdater/Internal/HotUpdaterCrashHandler.mm +0 -4
  218. package/lib/commonjs/DefaultResolver.js +0 -50
  219. package/lib/commonjs/DefaultResolver.js.map +0 -1
  220. package/lib/commonjs/DefaultResolver.spec.js +0 -144
  221. package/lib/commonjs/DefaultResolver.spec.js.map +0 -1
  222. package/lib/commonjs/fetchUpdateInfo.js.map +0 -1
  223. package/lib/module/DefaultResolver.js +0 -46
  224. package/lib/module/DefaultResolver.js.map +0 -1
  225. package/lib/module/DefaultResolver.spec.js +0 -144
  226. package/lib/module/DefaultResolver.spec.js.map +0 -1
  227. package/lib/module/fetchUpdateInfo.js.map +0 -1
  228. package/lib/typescript/commonjs/DefaultResolver.d.ts +0 -11
  229. package/lib/typescript/commonjs/DefaultResolver.d.ts.map +0 -1
  230. package/lib/typescript/commonjs/fetchUpdateInfo.d.ts +0 -7
  231. package/lib/typescript/commonjs/fetchUpdateInfo.d.ts.map +0 -1
  232. package/lib/typescript/module/DefaultResolver.d.ts +0 -11
  233. package/lib/typescript/module/DefaultResolver.d.ts.map +0 -1
  234. package/lib/typescript/module/fetchUpdateInfo.d.ts +0 -7
  235. package/lib/typescript/module/fetchUpdateInfo.d.ts.map +0 -1
  236. package/plugin/build/transformers.js +0 -314
  237. package/plugin/build/withHotUpdater.js +0 -228
  238. package/src/DefaultResolver.spec.ts +0 -193
  239. package/src/DefaultResolver.ts +0 -63
package/src/wrap.tsx CHANGED
@@ -1,307 +1,25 @@
1
1
  import React, { useEffect, useState } from "react";
2
2
 
3
3
  import { checkForUpdate } from "./checkForUpdate";
4
- import type { HotUpdaterError } from "./error";
5
4
  import { useEventCallback } from "./hooks/useEventCallback";
6
- import {
7
- getBundleId,
8
- type NotifyAppReadyResult,
9
- notifyAppReady as nativeNotifyAppReady,
10
- reload,
11
- } from "./native";
12
- import { type HotUpdaterState, useHotUpdaterStore } from "./store";
13
- import type { HotUpdaterBaseURL, HotUpdaterResolver } from "./types";
14
-
15
- export interface RunUpdateProcessResponse {
16
- status: "ROLLBACK" | "UPDATE" | "UP_TO_DATE";
17
- shouldForceUpdate: boolean;
18
- message: string | null;
19
- id: string;
20
- }
21
-
22
- type UpdateStatus =
23
- | "CHECK_FOR_UPDATE"
24
- | "UPDATING"
25
- | "UPDATE_PROCESS_COMPLETED";
26
-
27
- export type HotUpdaterFallbackComponentProps = {
28
- status: Exclude<UpdateStatus, "UPDATE_PROCESS_COMPLETED">;
29
- progress: number;
30
- downloadedBytes: HotUpdaterState["downloadedBytes"];
31
- totalBytes: HotUpdaterState["totalBytes"];
32
- message: string | null;
33
- artifactType: HotUpdaterState["artifactType"];
34
- details: HotUpdaterState["details"];
35
- };
36
-
37
- /**
38
- * Common options shared by HotUpdater initialization APIs.
39
- */
40
- interface CommonHotUpdaterOptions {
41
- /**
42
- * Custom request headers for update checks
43
- */
44
- requestHeaders?: Record<string, string>;
45
-
46
- /**
47
- * Request timeout in milliseconds
48
- * @default 5000
49
- */
50
- requestTimeout?: number;
51
-
52
- /**
53
- * Callback invoked when the app is ready and the native launch report is available.
54
- * Provides information about rollback recovery or stable state.
55
- *
56
- * @param result - Bundle state information
57
- * @param result.status - Current bundle state:
58
- * - "RECOVERED": App recovered from a crash, rollback occurred
59
- * - "STABLE": No changes, bundle is stable
60
- * @param result.crashedBundleId - Present only when status is "RECOVERED"
61
- *
62
- * @example
63
- * ```tsx
64
- * HotUpdater.init({
65
- * baseURL: "https://api.example.com",
66
- * onNotifyAppReady: ({ status, crashedBundleId }) => {
67
- * if (status === "RECOVERED") {
68
- * analytics.track("bundle_rollback", { crashedBundleId });
69
- * }
70
- * },
71
- * });
72
- * ```
73
- */
74
- onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
75
-
76
- /**
77
- * Default callback invoked when Hot Updater initialization or update checks
78
- * fail. Per-call `HotUpdater.checkForUpdate({ onError })` handlers override
79
- * this callback for that check.
80
- */
81
- onError?: (error: HotUpdaterError | Error | unknown) => void;
82
- }
83
-
84
- /**
85
- * Configuration with baseURL for standard server-based updates
86
- */
87
- interface BaseURLConfig {
88
- /**
89
- * Base URL for update server. Use a function to resolve it dynamically
90
- * before each update check.
91
- * @example "https://update.example.com"
92
- * @example () => getUpdateServerURL()
93
- */
94
- baseURL: HotUpdaterBaseURL;
95
-
96
- /**
97
- * Resolver is not allowed when using baseURL
98
- */
99
- resolver?: never;
100
- }
101
-
102
- /**
103
- * Configuration with resolver for custom network operations
104
- */
105
- interface ResolverConfig {
106
- /**
107
- * Custom resolver for network operations
108
- */
109
- resolver: HotUpdaterResolver;
110
-
111
- /**
112
- * baseURL is not allowed when using resolver
113
- */
114
- baseURL?: never;
115
- }
116
-
117
- /**
118
- * Union type ensuring baseURL and resolver are mutually exclusive
119
- */
120
- type NetworkConfig = BaseURLConfig | ResolverConfig;
121
-
122
- export type AutoUpdateOptions = CommonHotUpdaterOptions &
123
- NetworkConfig & {
124
- /**
125
- * Automatic update mode. This is the default and can be omitted.
126
- */
127
- updateMode?: "auto";
128
-
129
- /**
130
- * Update strategy
131
- * - "fingerprint": Use fingerprint hash to check for updates
132
- * - "appVersion": Use app version to check for updates
133
- */
134
- updateStrategy: "fingerprint" | "appVersion";
135
-
136
- /**
137
- * Component to show while downloading a new bundle update.
138
- *
139
- * When an update exists and the bundle is being downloaded, this component will block access
140
- * to the entry point and show download progress.
141
- *
142
- * @see {@link https://hot-updater.dev/docs/react-native-api/wrap#fallback-component}
143
- *
144
- * ```tsx
145
- * HotUpdater.wrap({
146
- * baseURL: "<update-server-url>",
147
- * updateStrategy: "appVersion",
148
- * fallbackComponent: ({ progress = 0 }) => (
149
- * <View style={styles.container}>
150
- * <Text style={styles.text}>Updating... {progress}%</Text>
151
- * </View>
152
- * )
153
- * })(App)
154
- * ```
155
- *
156
- * If not defined, the bundle will download in the background without blocking the screen.
157
- */
158
- fallbackComponent?: React.FC<HotUpdaterFallbackComponentProps>;
159
-
160
- onProgress?: (progress: number) => void;
161
-
162
- /**
163
- * When a force update exists, the app will automatically reload.
164
- * If `false`, When a force update exists, the app will not reload. `shouldForceUpdate` will be returned as `true` in `onUpdateProcessCompleted`.
165
- * If `true`, When a force update exists, the app will automatically reload.
166
- * @default true
167
- */
168
- reloadOnForceUpdate?: boolean;
169
-
170
- /**
171
- * Callback function that is called when the update process is completed.
172
- *
173
- * @see {@link https://hot-updater.dev/docs/react-native-api/wrap#onupdateprocesscompleted}
174
- */
175
- onUpdateProcessCompleted?: (response: RunUpdateProcessResponse) => void;
176
- };
177
-
178
- export type ManualUpdateOptions = CommonHotUpdaterOptions &
179
- NetworkConfig & {
180
- /**
181
- * @deprecated Replace manual `HotUpdater.wrap` with `HotUpdater.init`.
182
- *
183
- * ```tsx
184
- * import { HotUpdater } from "@hot-updater/react-native";
185
- *
186
- * HotUpdater.init({
187
- * baseURL: "<your-update-server-url>",
188
- * });
189
- *
190
- * export default App;
191
- * ```
192
- *
193
- * Then call `HotUpdater.checkForUpdate(...)` from your manual update flow.
194
- * See https://hot-updater.dev/docs/guides/custom-update
195
- */
196
- updateMode: "manual";
197
- };
198
-
199
- export type HotUpdaterInitOptions = CommonHotUpdaterOptions & NetworkConfig;
200
-
201
- export type HotUpdaterOptions = AutoUpdateOptions | ManualUpdateOptions;
202
-
203
- /**
204
- * Internal options after normalization in index.ts
205
- * Always has resolver (never baseURL)
206
- */
207
- type InternalCommonOptions = {
208
- resolver: HotUpdaterResolver;
209
- requestHeaders?: Record<string, string>;
210
- requestTimeout?: number;
211
- onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
212
- onError?: (error: HotUpdaterError | Error | unknown) => void;
213
- };
214
-
215
- type InternalAutoUpdateOptions = InternalCommonOptions & {
216
- updateStrategy: "fingerprint" | "appVersion";
217
- updateMode: "auto";
218
- fallbackComponent?: React.FC<HotUpdaterFallbackComponentProps>;
219
- onProgress?: (progress: number) => void;
220
- reloadOnForceUpdate?: boolean;
221
- onUpdateProcessCompleted?: (response: RunUpdateProcessResponse) => void;
222
- };
223
-
224
- type InternalManualUpdateOptions = InternalCommonOptions & {
225
- updateMode: "manual";
226
- };
227
-
228
- export type InternalInitOptions = InternalCommonOptions;
229
-
230
- export type InternalWrapOptions =
231
- | InternalAutoUpdateOptions
232
- | InternalManualUpdateOptions;
233
-
234
- type RequestAnimationFrame = (callback: (timestamp: number) => void) => number;
235
-
236
- let didWarnManualWrapDeprecation = false;
237
-
238
- const warnManualWrapDeprecation = () => {
239
- if (didWarnManualWrapDeprecation) {
240
- return;
241
- }
242
-
243
- didWarnManualWrapDeprecation = true;
244
- console.warn(
245
- '[HotUpdater] HotUpdater.wrap({ updateMode: "manual" }) is deprecated. ' +
246
- "Move the same baseURL/resolver options to HotUpdater.init({ ... }), " +
247
- "export your root component directly, and call " +
248
- "HotUpdater.checkForUpdate(...) from your manual update flow. " +
249
- "See https://hot-updater.dev/docs/guides/custom-update",
250
- );
251
- };
252
-
253
- const waitForNextFrame = () =>
254
- new Promise<void>((resolve) => {
255
- const requestAnimationFrame = (
256
- globalThis as typeof globalThis & {
257
- requestAnimationFrame?: RequestAnimationFrame;
258
- }
259
- )?.requestAnimationFrame;
260
-
261
- if (requestAnimationFrame) {
262
- requestAnimationFrame(() => resolve());
263
- return;
264
- }
265
-
266
- void Promise.resolve().then(resolve);
267
- });
268
-
269
- /**
270
- * Helper function to handle notifyAppReady flow
271
- */
272
- const handleNotifyAppReady = async (options: {
273
- resolver?: HotUpdaterResolver;
274
- requestHeaders?: Record<string, string>;
275
- requestTimeout?: number;
276
- onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
277
- onError?: (error: HotUpdaterError | Error | unknown) => void;
278
- }): Promise<void> => {
279
- await waitForNextFrame();
280
-
281
- try {
282
- const nativeResult = nativeNotifyAppReady();
283
-
284
- // If resolver.notifyAppReady exists, call it with simplified params
285
- if (options.resolver?.notifyAppReady) {
286
- await options.resolver
287
- .notifyAppReady({
288
- status: nativeResult.status,
289
- crashedBundleId: nativeResult.crashedBundleId,
290
- requestHeaders: options.requestHeaders,
291
- requestTimeout: options.requestTimeout,
292
- })
293
- .catch((e: unknown) => {
294
- options.onError?.(e);
295
- console.warn("[HotUpdater] Resolver notifyAppReady failed:", e);
296
- });
297
- }
298
-
299
- options.onNotifyAppReady?.(nativeResult);
300
- } catch (e) {
301
- options.onError?.(e);
302
- console.warn("[HotUpdater] Failed to notify app ready:", e);
303
- }
304
- };
5
+ import { getBundleId, reload } from "./native";
6
+ import { handleNotifyAppReady } from "./notifyAppReadyAnalytics";
7
+ import { useHotUpdaterStore } from "./store";
8
+ import type {
9
+ InternalInitOptions,
10
+ InternalWrapOptions,
11
+ UpdateStatus,
12
+ } from "./wrap.types";
13
+
14
+ export type {
15
+ AutoUpdateOptions,
16
+ HotUpdaterFallbackComponentProps,
17
+ HotUpdaterInitOptions,
18
+ HotUpdaterOptions,
19
+ InternalInitOptions,
20
+ InternalWrapOptions,
21
+ RunUpdateProcessResponse,
22
+ } from "./wrap.types";
305
23
 
306
24
  export function init(options: InternalInitOptions): void {
307
25
  void handleNotifyAppReady(options);
@@ -312,22 +30,6 @@ export function wrap(
312
30
  ): <P extends object>(
313
31
  WrappedComponent: React.ComponentType<P>,
314
32
  ) => React.ComponentType<P> {
315
- if (options.updateMode === "manual") {
316
- warnManualWrapDeprecation();
317
-
318
- return <P extends object>(WrappedComponent: React.ComponentType<P>) => {
319
- const ManualHOC: React.FC<P> = (props: P) => {
320
- useEffect(() => {
321
- void handleNotifyAppReady(options);
322
- }, []);
323
-
324
- return <WrappedComponent {...props} />;
325
- };
326
-
327
- return ManualHOC as React.ComponentType<P>;
328
- };
329
- }
330
-
331
33
  const { reloadOnForceUpdate = true, ...restOptions } = options;
332
34
 
333
35
  return <P extends object>(WrappedComponent: React.ComponentType<P>) => {
@@ -344,7 +46,8 @@ export function wrap(
344
46
  setUpdateStatus("CHECK_FOR_UPDATE");
345
47
 
346
48
  const updateInfo = await checkForUpdate({
347
- resolver: restOptions.resolver,
49
+ analytics: restOptions.analytics,
50
+ client: restOptions.client,
348
51
  updateStrategy: restOptions.updateStrategy,
349
52
  requestHeaders: restOptions.requestHeaders,
350
53
  requestTimeout: restOptions.requestTimeout,
@@ -401,7 +104,9 @@ export function wrap(
401
104
 
402
105
  setUpdateStatus("UPDATE_PROCESS_COMPLETED");
403
106
  } catch (error) {
404
- restOptions.onError?.(error);
107
+ const normalizedError =
108
+ error instanceof Error ? error : new Error(String(error));
109
+ restOptions.onError?.(normalizedError);
405
110
  setUpdateStatus("UPDATE_PROCESS_COMPLETED");
406
111
  }
407
112
  });
@@ -0,0 +1,78 @@
1
+ import type React from "react";
2
+
3
+ import type { HotUpdaterError } from "./error";
4
+ import type { HotUpdaterHttpClient } from "./httpClient";
5
+ import type { NotifyAppReadyResult } from "./native";
6
+ import type { HotUpdaterState } from "./store";
7
+ import type { HotUpdaterBaseURL } from "./types";
8
+
9
+ export interface RunUpdateProcessResponse {
10
+ status: "ROLLBACK" | "UPDATE" | "UP_TO_DATE";
11
+ shouldForceUpdate: boolean;
12
+ message: string | null;
13
+ id: string;
14
+ }
15
+
16
+ export type UpdateStatus =
17
+ | "CHECK_FOR_UPDATE"
18
+ | "UPDATING"
19
+ | "UPDATE_PROCESS_COMPLETED";
20
+
21
+ export type HotUpdaterFallbackComponentProps = {
22
+ status: Exclude<UpdateStatus, "UPDATE_PROCESS_COMPLETED">;
23
+ progress: number;
24
+ downloadedBytes: HotUpdaterState["downloadedBytes"];
25
+ totalBytes: HotUpdaterState["totalBytes"];
26
+ message: string | null;
27
+ artifactType: HotUpdaterState["artifactType"];
28
+ details: HotUpdaterState["details"];
29
+ };
30
+
31
+ interface CommonHotUpdaterOptions {
32
+ /**
33
+ * Sends app-ready transitions and same-Bundle Release adoptions to the
34
+ * configured server. Omit or set to `false` to disable client reporting.
35
+ */
36
+ analytics?: boolean;
37
+ /** Base URL of a server exposing the Hot Updater v1 client HTTP protocol. */
38
+ baseURL: HotUpdaterBaseURL;
39
+ requestHeaders?: Record<string, string>;
40
+ requestTimeout?: number;
41
+ onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
42
+ onError?: (error: HotUpdaterError | Error | unknown) => void;
43
+ }
44
+
45
+ export type AutoUpdateOptions = CommonHotUpdaterOptions & {
46
+ updateStrategy: "fingerprint" | "appVersion";
47
+ fallbackComponent?: React.FC<HotUpdaterFallbackComponentProps>;
48
+ onProgress?: (progress: number) => void;
49
+ reloadOnForceUpdate?: boolean;
50
+ onUpdateProcessCompleted?: (response: RunUpdateProcessResponse) => void;
51
+ };
52
+
53
+ export type HotUpdaterInitOptions = CommonHotUpdaterOptions;
54
+
55
+ export type HotUpdaterOptions = AutoUpdateOptions;
56
+
57
+ type InternalCommonOptions = {
58
+ analytics?: boolean;
59
+ client: HotUpdaterHttpClient;
60
+ requestHeaders?: Record<string, string>;
61
+ requestTimeout?: number;
62
+ onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
63
+ onError?: (error: HotUpdaterError | Error | unknown) => void;
64
+ };
65
+
66
+ type InternalAutoUpdateOptions = InternalCommonOptions & {
67
+ updateStrategy: "fingerprint" | "appVersion";
68
+ fallbackComponent?: React.FC<HotUpdaterFallbackComponentProps>;
69
+ onProgress?: (progress: number) => void;
70
+ reloadOnForceUpdate?: boolean;
71
+ onUpdateProcessCompleted?: (response: RunUpdateProcessResponse) => void;
72
+ };
73
+
74
+ export type InternalInitOptions = InternalCommonOptions & {
75
+ analytics?: boolean;
76
+ };
77
+
78
+ export type InternalWrapOptions = InternalAutoUpdateOptions;
@@ -1,45 +0,0 @@
1
- package com.hotupdater
2
-
3
- import android.content.Context
4
-
5
- /**
6
- * Utility class for string resource lookup operations
7
- */
8
- object StringResourceUtils {
9
- /**
10
- * Resolves a string resource ID with namespace fallback.
11
- * Handles AGP 7.0+ where namespace and applicationId are decoupled.
12
- * @param context Application context
13
- * @param resourceName The string resource name to resolve
14
- * @return The resolved resource ID, or 0 if not found
15
- */
16
- fun getIdentifier(
17
- context: Context,
18
- resourceName: String,
19
- ): Int {
20
- var resourceId =
21
- context.resources.getIdentifier(
22
- resourceName,
23
- "string",
24
- context.packageName,
25
- )
26
-
27
- // Fallback: try namespace derived from Application class package
28
- if (resourceId == 0) {
29
- val appClassName = context.applicationInfo.className
30
- if (appClassName != null) {
31
- val namespace = appClassName.substringBeforeLast('.')
32
- if (namespace != context.packageName) {
33
- resourceId =
34
- context.resources.getIdentifier(
35
- resourceName,
36
- "string",
37
- namespace,
38
- )
39
- }
40
- }
41
- }
42
-
43
- return resourceId
44
- }
45
- }
package/app.plugin.js DELETED
@@ -1 +0,0 @@
1
- module.exports = require("./plugin/build/withHotUpdater");
@@ -1,7 +0,0 @@
1
- #ifndef HotUpdaterCrashHandler_h
2
- #define HotUpdaterCrashHandler_h
3
-
4
- // Compatibility shim for stale CocoaPods projects that still reference the
5
- // old crash-handler file names before `pod install` refreshes the source list.
6
-
7
- #endif /* HotUpdaterCrashHandler_h */
@@ -1,4 +0,0 @@
1
- #import "HotUpdaterCrashHandler.h"
2
-
3
- // Compatibility shim for stale CocoaPods projects that still compile the old
4
- // crash-handler translation unit. Recovery logic now lives in `HotUpdater.mm`.
@@ -1,50 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.createDefaultResolver = createDefaultResolver;
7
- var _fetchUpdateInfo = require("./fetchUpdateInfo.js");
8
- var _sdkVersion = require("./sdkVersion.js");
9
- const resolveBaseURL = async baseURL => {
10
- const resolvedBaseURL = typeof baseURL === "function" ? await baseURL() : baseURL;
11
- if (!resolvedBaseURL) {
12
- throw new Error("baseURL resolver must return a non-empty string");
13
- }
14
- return resolvedBaseURL;
15
- };
16
-
17
- /**
18
- * Creates a default resolver that uses baseURL for network operations.
19
- * This encapsulates the existing baseURL logic into a resolver.
20
- *
21
- * @param baseURL - The base URL for the update server, or a function that
22
- * resolves it before each update check.
23
- * @returns A HotUpdaterResolver that uses the baseURL
24
- */
25
- function createDefaultResolver(baseURL) {
26
- return {
27
- checkUpdate: async params => {
28
- const resolvedBaseURL = (await resolveBaseURL(baseURL)).replace(/\/+$/, "");
29
- let url;
30
- const cohortPath = `/${encodeURIComponent(params.cohort)}`;
31
- if (params.updateStrategy === "fingerprint") {
32
- if (!params.fingerprintHash) {
33
- throw new Error("Fingerprint hash is required");
34
- }
35
- url = `${resolvedBaseURL}/fingerprint/${params.platform}/${params.fingerprintHash}/${params.channel}/${params.minBundleId}/${params.bundleId}${cohortPath}`;
36
- } else {
37
- url = `${resolvedBaseURL}/app-version/${params.platform}/${params.appVersion}/${params.channel}/${params.minBundleId}/${params.bundleId}${cohortPath}`;
38
- }
39
- return (0, _fetchUpdateInfo.fetchUpdateInfo)({
40
- url,
41
- requestHeaders: {
42
- ...params.requestHeaders,
43
- "Hot-Updater-SDK-Version": _sdkVersion.HOT_UPDATER_SDK_VERSION
44
- },
45
- requestTimeout: params.requestTimeout
46
- });
47
- }
48
- };
49
- }
50
- //# sourceMappingURL=DefaultResolver.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_fetchUpdateInfo","require","_sdkVersion","resolveBaseURL","baseURL","resolvedBaseURL","Error","createDefaultResolver","checkUpdate","params","replace","url","cohortPath","encodeURIComponent","cohort","updateStrategy","fingerprintHash","platform","channel","minBundleId","bundleId","appVersion","fetchUpdateInfo","requestHeaders","HOT_UPDATER_SDK_VERSION","requestTimeout"],"sourceRoot":"../../src","sources":["DefaultResolver.ts"],"mappings":";;;;;;AAEA,IAAAA,gBAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AAOA,MAAME,cAAc,GAAG,MAAOC,OAA0B,IAAsB;EAC5E,MAAMC,eAAe,GACnB,OAAOD,OAAO,KAAK,UAAU,GAAG,MAAMA,OAAO,CAAC,CAAC,GAAGA,OAAO;EAE3D,IAAI,CAACC,eAAe,EAAE;IACpB,MAAM,IAAIC,KAAK,CAAC,iDAAiD,CAAC;EACpE;EAEA,OAAOD,eAAe;AACxB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,qBAAqBA,CACnCH,OAA0B,EACN;EACpB,OAAO;IACLI,WAAW,EAAE,MACXC,MAAiC,IACC;MAClC,MAAMJ,eAAe,GAAG,CAAC,MAAMF,cAAc,CAACC,OAAO,CAAC,EAAEM,OAAO,CAC7D,MAAM,EACN,EACF,CAAC;MACD,IAAIC,GAAW;MACf,MAAMC,UAAU,GAAG,IAAIC,kBAAkB,CAACJ,MAAM,CAACK,MAAM,CAAC,EAAE;MAE1D,IAAIL,MAAM,CAACM,cAAc,KAAK,aAAa,EAAE;QAC3C,IAAI,CAACN,MAAM,CAACO,eAAe,EAAE;UAC3B,MAAM,IAAIV,KAAK,CAAC,8BAA8B,CAAC;QACjD;QACAK,GAAG,GAAG,GAAGN,eAAe,gBAAgBI,MAAM,CAACQ,QAAQ,IAAIR,MAAM,CAACO,eAAe,IAAIP,MAAM,CAACS,OAAO,IAAIT,MAAM,CAACU,WAAW,IAAIV,MAAM,CAACW,QAAQ,GAAGR,UAAU,EAAE;MAC7J,CAAC,MAAM;QACLD,GAAG,GAAG,GAAGN,eAAe,gBAAgBI,MAAM,CAACQ,QAAQ,IAAIR,MAAM,CAACY,UAAU,IAAIZ,MAAM,CAACS,OAAO,IAAIT,MAAM,CAACU,WAAW,IAAIV,MAAM,CAACW,QAAQ,GAAGR,UAAU,EAAE;MACxJ;MAEA,OAAO,IAAAU,gCAAe,EAAC;QACrBX,GAAG;QACHY,cAAc,EAAE;UACd,GAAGd,MAAM,CAACc,cAAc;UACxB,yBAAyB,EAAEC;QAC7B,CAAC;QACDC,cAAc,EAAEhB,MAAM,CAACgB;MACzB,CAAC,CAAC;IACJ;EACF,CAAC;AACH","ignoreList":[]}