@hot-updater/react-native 0.36.7 → 1.0.0-rc.1

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 +47 -70
  37. package/lib/commonjs/index.js.map +1 -1
  38. package/lib/commonjs/index.spec.js +115 -159
  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 -53
  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 +48 -65
  90. package/lib/module/index.js.map +1 -1
  91. package/lib/module/index.spec.js +115 -159
  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 -49
  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 +31 -40
  137. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  138. package/lib/typescript/commonjs/native.d.ts +84 -17
  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 +31 -40
  167. package/lib/typescript/module/index.d.ts.map +1 -1
  168. package/lib/typescript/module/native.d.ts +84 -17
  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 +367 -96
  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 +108 -201
  196. package/src/index.ts +68 -91
  197. package/src/iosInterop.spec.ts +30 -0
  198. package/src/native.spec.ts +226 -10
  199. package/src/native.ts +385 -81
  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
@@ -1,195 +1,6 @@
1
1
  import React from "react";
2
- import type { HotUpdaterError } from "./error";
3
- import { type NotifyAppReadyResult } from "./native";
4
- import { type HotUpdaterState } from "./store";
5
- import type { HotUpdaterBaseURL, HotUpdaterResolver } from "./types";
6
- export interface RunUpdateProcessResponse {
7
- status: "ROLLBACK" | "UPDATE" | "UP_TO_DATE";
8
- shouldForceUpdate: boolean;
9
- message: string | null;
10
- id: string;
11
- }
12
- type UpdateStatus = "CHECK_FOR_UPDATE" | "UPDATING" | "UPDATE_PROCESS_COMPLETED";
13
- export type HotUpdaterFallbackComponentProps = {
14
- status: Exclude<UpdateStatus, "UPDATE_PROCESS_COMPLETED">;
15
- progress: number;
16
- downloadedBytes: HotUpdaterState["downloadedBytes"];
17
- totalBytes: HotUpdaterState["totalBytes"];
18
- message: string | null;
19
- artifactType: HotUpdaterState["artifactType"];
20
- details: HotUpdaterState["details"];
21
- };
22
- /**
23
- * Common options shared by HotUpdater initialization APIs.
24
- */
25
- interface CommonHotUpdaterOptions {
26
- /**
27
- * Custom request headers for update checks
28
- */
29
- requestHeaders?: Record<string, string>;
30
- /**
31
- * Request timeout in milliseconds
32
- * @default 5000
33
- */
34
- requestTimeout?: number;
35
- /**
36
- * Callback invoked when the app is ready and the native launch report is available.
37
- * Provides information about rollback recovery or stable state.
38
- *
39
- * @param result - Bundle state information
40
- * @param result.status - Current bundle state:
41
- * - "RECOVERED": App recovered from a crash, rollback occurred
42
- * - "STABLE": No changes, bundle is stable
43
- * @param result.crashedBundleId - Present only when status is "RECOVERED"
44
- *
45
- * @example
46
- * ```tsx
47
- * HotUpdater.init({
48
- * baseURL: "https://api.example.com",
49
- * onNotifyAppReady: ({ status, crashedBundleId }) => {
50
- * if (status === "RECOVERED") {
51
- * analytics.track("bundle_rollback", { crashedBundleId });
52
- * }
53
- * },
54
- * });
55
- * ```
56
- */
57
- onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
58
- /**
59
- * Default callback invoked when Hot Updater initialization or update checks
60
- * fail. Per-call `HotUpdater.checkForUpdate({ onError })` handlers override
61
- * this callback for that check.
62
- */
63
- onError?: (error: HotUpdaterError | Error | unknown) => void;
64
- }
65
- /**
66
- * Configuration with baseURL for standard server-based updates
67
- */
68
- interface BaseURLConfig {
69
- /**
70
- * Base URL for update server. Use a function to resolve it dynamically
71
- * before each update check.
72
- * @example "https://update.example.com"
73
- * @example () => getUpdateServerURL()
74
- */
75
- baseURL: HotUpdaterBaseURL;
76
- /**
77
- * Resolver is not allowed when using baseURL
78
- */
79
- resolver?: never;
80
- }
81
- /**
82
- * Configuration with resolver for custom network operations
83
- */
84
- interface ResolverConfig {
85
- /**
86
- * Custom resolver for network operations
87
- */
88
- resolver: HotUpdaterResolver;
89
- /**
90
- * baseURL is not allowed when using resolver
91
- */
92
- baseURL?: never;
93
- }
94
- /**
95
- * Union type ensuring baseURL and resolver are mutually exclusive
96
- */
97
- type NetworkConfig = BaseURLConfig | ResolverConfig;
98
- export type AutoUpdateOptions = CommonHotUpdaterOptions & NetworkConfig & {
99
- /**
100
- * Automatic update mode. This is the default and can be omitted.
101
- */
102
- updateMode?: "auto";
103
- /**
104
- * Update strategy
105
- * - "fingerprint": Use fingerprint hash to check for updates
106
- * - "appVersion": Use app version to check for updates
107
- */
108
- updateStrategy: "fingerprint" | "appVersion";
109
- /**
110
- * Component to show while downloading a new bundle update.
111
- *
112
- * When an update exists and the bundle is being downloaded, this component will block access
113
- * to the entry point and show download progress.
114
- *
115
- * @see {@link https://hot-updater.dev/docs/react-native-api/wrap#fallback-component}
116
- *
117
- * ```tsx
118
- * HotUpdater.wrap({
119
- * baseURL: "<update-server-url>",
120
- * updateStrategy: "appVersion",
121
- * fallbackComponent: ({ progress = 0 }) => (
122
- * <View style={styles.container}>
123
- * <Text style={styles.text}>Updating... {progress}%</Text>
124
- * </View>
125
- * )
126
- * })(App)
127
- * ```
128
- *
129
- * If not defined, the bundle will download in the background without blocking the screen.
130
- */
131
- fallbackComponent?: React.FC<HotUpdaterFallbackComponentProps>;
132
- onProgress?: (progress: number) => void;
133
- /**
134
- * When a force update exists, the app will automatically reload.
135
- * If `false`, When a force update exists, the app will not reload. `shouldForceUpdate` will be returned as `true` in `onUpdateProcessCompleted`.
136
- * If `true`, When a force update exists, the app will automatically reload.
137
- * @default true
138
- */
139
- reloadOnForceUpdate?: boolean;
140
- /**
141
- * Callback function that is called when the update process is completed.
142
- *
143
- * @see {@link https://hot-updater.dev/docs/react-native-api/wrap#onupdateprocesscompleted}
144
- */
145
- onUpdateProcessCompleted?: (response: RunUpdateProcessResponse) => void;
146
- };
147
- export type ManualUpdateOptions = CommonHotUpdaterOptions & NetworkConfig & {
148
- /**
149
- * @deprecated Replace manual `HotUpdater.wrap` with `HotUpdater.init`.
150
- *
151
- * ```tsx
152
- * import { HotUpdater } from "@hot-updater/react-native";
153
- *
154
- * HotUpdater.init({
155
- * baseURL: "<your-update-server-url>",
156
- * });
157
- *
158
- * export default App;
159
- * ```
160
- *
161
- * Then call `HotUpdater.checkForUpdate(...)` from your manual update flow.
162
- * See https://hot-updater.dev/docs/guides/custom-update
163
- */
164
- updateMode: "manual";
165
- };
166
- export type HotUpdaterInitOptions = CommonHotUpdaterOptions & NetworkConfig;
167
- export type HotUpdaterOptions = AutoUpdateOptions | ManualUpdateOptions;
168
- /**
169
- * Internal options after normalization in index.ts
170
- * Always has resolver (never baseURL)
171
- */
172
- type InternalCommonOptions = {
173
- resolver: HotUpdaterResolver;
174
- requestHeaders?: Record<string, string>;
175
- requestTimeout?: number;
176
- onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
177
- onError?: (error: HotUpdaterError | Error | unknown) => void;
178
- };
179
- type InternalAutoUpdateOptions = InternalCommonOptions & {
180
- updateStrategy: "fingerprint" | "appVersion";
181
- updateMode: "auto";
182
- fallbackComponent?: React.FC<HotUpdaterFallbackComponentProps>;
183
- onProgress?: (progress: number) => void;
184
- reloadOnForceUpdate?: boolean;
185
- onUpdateProcessCompleted?: (response: RunUpdateProcessResponse) => void;
186
- };
187
- type InternalManualUpdateOptions = InternalCommonOptions & {
188
- updateMode: "manual";
189
- };
190
- export type InternalInitOptions = InternalCommonOptions;
191
- export type InternalWrapOptions = InternalAutoUpdateOptions | InternalManualUpdateOptions;
2
+ import type { InternalInitOptions, InternalWrapOptions } from "./wrap.types";
3
+ export type { AutoUpdateOptions, HotUpdaterFallbackComponentProps, HotUpdaterInitOptions, HotUpdaterOptions, InternalInitOptions, InternalWrapOptions, RunUpdateProcessResponse, } from "./wrap.types";
192
4
  export declare function init(options: InternalInitOptions): void;
193
5
  export declare function wrap(options: InternalWrapOptions): <P extends object>(WrappedComponent: React.ComponentType<P>) => React.ComponentType<P>;
194
- export {};
195
6
  //# sourceMappingURL=wrap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../../src/wrap.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../../src/wrap.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAOnD,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EAEpB,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,iBAAiB,EACjB,gCAAgC,EAChC,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,cAAc,CAAC;AAEtB,wBAAgB,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAEvD;AAED,wBAAgB,IAAI,CAClB,OAAO,EAAE,mBAAmB,GAC3B,CAAC,CAAC,SAAS,MAAM,EAClB,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KACrC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAuH1B"}
@@ -0,0 +1,65 @@
1
+ import type React from "react";
2
+ import type { HotUpdaterError } from "./error";
3
+ import type { HotUpdaterHttpClient } from "./httpClient";
4
+ import type { NotifyAppReadyResult } from "./native";
5
+ import type { HotUpdaterState } from "./store";
6
+ import type { HotUpdaterBaseURL } from "./types";
7
+ export interface RunUpdateProcessResponse {
8
+ status: "ROLLBACK" | "UPDATE" | "UP_TO_DATE";
9
+ shouldForceUpdate: boolean;
10
+ message: string | null;
11
+ id: string;
12
+ }
13
+ export type UpdateStatus = "CHECK_FOR_UPDATE" | "UPDATING" | "UPDATE_PROCESS_COMPLETED";
14
+ export type HotUpdaterFallbackComponentProps = {
15
+ status: Exclude<UpdateStatus, "UPDATE_PROCESS_COMPLETED">;
16
+ progress: number;
17
+ downloadedBytes: HotUpdaterState["downloadedBytes"];
18
+ totalBytes: HotUpdaterState["totalBytes"];
19
+ message: string | null;
20
+ artifactType: HotUpdaterState["artifactType"];
21
+ details: HotUpdaterState["details"];
22
+ };
23
+ interface CommonHotUpdaterOptions {
24
+ /**
25
+ * Sends app-ready transitions and same-Bundle Release adoptions to the
26
+ * configured server. Omit or set to `false` to disable client reporting.
27
+ */
28
+ analytics?: boolean;
29
+ /** Base URL of a server exposing the Hot Updater v1 client HTTP protocol. */
30
+ baseURL: HotUpdaterBaseURL;
31
+ requestHeaders?: Record<string, string>;
32
+ requestTimeout?: number;
33
+ onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
34
+ onError?: (error: HotUpdaterError | Error | unknown) => void;
35
+ }
36
+ export type AutoUpdateOptions = CommonHotUpdaterOptions & {
37
+ updateStrategy: "fingerprint" | "appVersion";
38
+ fallbackComponent?: React.FC<HotUpdaterFallbackComponentProps>;
39
+ onProgress?: (progress: number) => void;
40
+ reloadOnForceUpdate?: boolean;
41
+ onUpdateProcessCompleted?: (response: RunUpdateProcessResponse) => void;
42
+ };
43
+ export type HotUpdaterInitOptions = CommonHotUpdaterOptions;
44
+ export type HotUpdaterOptions = AutoUpdateOptions;
45
+ type InternalCommonOptions = {
46
+ analytics?: boolean;
47
+ client: HotUpdaterHttpClient;
48
+ requestHeaders?: Record<string, string>;
49
+ requestTimeout?: number;
50
+ onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
51
+ onError?: (error: HotUpdaterError | Error | unknown) => void;
52
+ };
53
+ type InternalAutoUpdateOptions = InternalCommonOptions & {
54
+ updateStrategy: "fingerprint" | "appVersion";
55
+ fallbackComponent?: React.FC<HotUpdaterFallbackComponentProps>;
56
+ onProgress?: (progress: number) => void;
57
+ reloadOnForceUpdate?: boolean;
58
+ onUpdateProcessCompleted?: (response: RunUpdateProcessResponse) => void;
59
+ };
60
+ export type InternalInitOptions = InternalCommonOptions & {
61
+ analytics?: boolean;
62
+ };
63
+ export type InternalWrapOptions = InternalAutoUpdateOptions;
64
+ export {};
65
+ //# sourceMappingURL=wrap.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap.types.d.ts","sourceRoot":"","sources":["../../../src/wrap.types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hot-updater/react-native",
3
- "version": "0.36.7",
3
+ "version": "1.0.0-rc.1",
4
4
  "description": "React Native OTA solution for self-hosted",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./lib/commonjs/index.js",
@@ -18,8 +18,7 @@
18
18
  "default": "./lib/commonjs/index.js"
19
19
  }
20
20
  },
21
- "./package.json": "./package.json",
22
- "./app.plugin.js": "./app.plugin.js"
21
+ "./package.json": "./package.json"
23
22
  },
24
23
  "files": [
25
24
  "src",
@@ -27,8 +26,6 @@
27
26
  "android",
28
27
  "ios",
29
28
  "cpp",
30
- "app.plugin.js",
31
- "plugin/build",
32
29
  "*.podspec",
33
30
  "react-native.config.js",
34
31
  "!ios/build",
@@ -99,17 +96,7 @@
99
96
  "javaPackageName": "com.hotupdater"
100
97
  }
101
98
  },
102
- "peerDependenciesMeta": {
103
- "expo": {
104
- "optional": true
105
- },
106
- "hot-updater": {
107
- "optional": true
108
- }
109
- },
110
99
  "peerDependencies": {
111
- "expo": ">=50.0.0",
112
- "hot-updater": "*",
113
100
  "react": "*",
114
101
  "react-native": "*"
115
102
  },
@@ -122,7 +109,6 @@
122
109
  "@types/react-dom": "19.1.3",
123
110
  "@types/use-sync-external-store": "^0.0.6",
124
111
  "del-cli": "^6.0.0",
125
- "expo": "^50.0.0",
126
112
  "jsdom": "29.1.1",
127
113
  "oxc-transform": "0.141.0",
128
114
  "react": "19.1.3",
@@ -130,19 +116,15 @@
130
116
  "react-native": "0.79.1",
131
117
  "react-native-builder-bob": "0.41.0",
132
118
  "@typescript/native": "npm:typescript@^7.0.2",
133
- "typescript": "npm:@typescript/typescript6@^6.0.2",
134
- "hot-updater": "0.36.7"
119
+ "typescript": "npm:@typescript/typescript6@^6.0.2"
135
120
  },
136
121
  "dependencies": {
137
122
  "use-sync-external-store": "1.5.0",
138
- "@hot-updater/core": "0.36.7",
139
- "@hot-updater/js": "0.36.7",
140
- "@hot-updater/plugin-core": "0.36.7",
141
- "@hot-updater/cli-tools": "0.36.7"
123
+ "@hot-updater/core": "1.0.0-rc.0",
124
+ "@hot-updater/plugin-core": "1.0.0-rc.0"
142
125
  },
143
126
  "scripts": {
144
- "build": "node ./scripts/sync-sdk-version.mjs run -- bob build && tsc -p plugin/tsconfig.build.json",
145
- "build:plugin": "tsc -p plugin/tsconfig.build.json",
127
+ "build": "node ./scripts/sync-sdk-version.mjs run -- bob build",
146
128
  "sync:sdk-version": "node ./scripts/sync-sdk-version.mjs",
147
129
  "test:type": "tsc --noEmit",
148
130
  "test": "vitest",
@@ -0,0 +1,63 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+
3
+ const nativeModule = vi.hoisted(
4
+ () => ({}) as Record<string, ReturnType<typeof vi.fn>>,
5
+ );
6
+
7
+ vi.mock("./specs/NativeHotUpdater", () => ({ default: nativeModule }));
8
+
9
+ import {
10
+ readNativeReleaseCatalogCache,
11
+ removeNativeReleaseCatalogCache,
12
+ writeNativeReleaseCatalogCache,
13
+ } from "./catalogCacheNative";
14
+
15
+ describe("Release Catalog native cache", () => {
16
+ beforeEach(() => {
17
+ for (const key of Object.keys(nativeModule)) delete nativeModule[key];
18
+ });
19
+
20
+ it("fails fast when the v1 native cache API is missing", async () => {
21
+ await expect(readNativeReleaseCatalogCache("partition")).rejects.toThrow(
22
+ "Native module is missing 'getReleaseCatalogCache()'. Rebuild the native app before using Release catalogs.",
23
+ );
24
+ await expect(
25
+ writeNativeReleaseCatalogCache("partition", "payload"),
26
+ ).rejects.toThrow(
27
+ "Native module is missing 'setReleaseCatalogCache()'. Rebuild the native app before using Release catalogs.",
28
+ );
29
+ await expect(removeNativeReleaseCatalogCache("partition")).rejects.toThrow(
30
+ "Native module is missing 'removeReleaseCatalogCache()'. Rebuild the native app before using Release catalogs.",
31
+ );
32
+ });
33
+
34
+ it("normalizes an undefined iOS TurboModule cache miss to null", async () => {
35
+ nativeModule.getReleaseCatalogCache = vi.fn().mockResolvedValue(undefined);
36
+
37
+ await expect(
38
+ readNativeReleaseCatalogCache("partition"),
39
+ ).resolves.toBeNull();
40
+ });
41
+
42
+ it("treats native cache I/O failures as misses without hiding network work", async () => {
43
+ nativeModule.getReleaseCatalogCache = vi
44
+ .fn()
45
+ .mockRejectedValue(new Error("read"));
46
+ nativeModule.setReleaseCatalogCache = vi
47
+ .fn()
48
+ .mockRejectedValue(new Error("write"));
49
+ nativeModule.removeReleaseCatalogCache = vi
50
+ .fn()
51
+ .mockRejectedValue(new Error("remove"));
52
+
53
+ await expect(
54
+ readNativeReleaseCatalogCache("partition"),
55
+ ).resolves.toBeNull();
56
+ await expect(
57
+ writeNativeReleaseCatalogCache("partition", "payload"),
58
+ ).resolves.toBe(false);
59
+ await expect(
60
+ removeNativeReleaseCatalogCache("partition"),
61
+ ).resolves.toBeUndefined();
62
+ });
63
+ });
@@ -0,0 +1,74 @@
1
+ import HotUpdaterNative from "./specs/NativeHotUpdater";
2
+
3
+ type CatalogCacheNativeModule = {
4
+ getReleaseCatalogCache?: (partition: string) => Promise<string | null>;
5
+ removeReleaseCatalogCache?: (partition: string) => Promise<boolean>;
6
+ setReleaseCatalogCache?: (
7
+ partition: string,
8
+ payload: string,
9
+ ) => Promise<boolean>;
10
+ };
11
+
12
+ type CatalogCacheNativeMethodName = keyof CatalogCacheNativeModule;
13
+
14
+ const getModule = () =>
15
+ HotUpdaterNative as typeof HotUpdaterNative & CatalogCacheNativeModule;
16
+
17
+ const requireMethod = <T>(
18
+ method: T | undefined,
19
+ name: CatalogCacheNativeMethodName,
20
+ ): T => {
21
+ if (typeof method !== "function") {
22
+ throw new Error(
23
+ `[HotUpdater] Native module is missing '${name}()'. Rebuild the native app before using Release catalogs.`,
24
+ );
25
+ }
26
+ return method;
27
+ };
28
+
29
+ export const readNativeReleaseCatalogCache = async (
30
+ partition: string,
31
+ ): Promise<string | null> => {
32
+ const method = requireMethod(
33
+ getModule().getReleaseCatalogCache,
34
+ "getReleaseCatalogCache",
35
+ );
36
+
37
+ try {
38
+ const value = await method.call(HotUpdaterNative, partition);
39
+ return typeof value === "string" ? value : null;
40
+ } catch {
41
+ return null;
42
+ }
43
+ };
44
+
45
+ export const writeNativeReleaseCatalogCache = async (
46
+ partition: string,
47
+ payload: string,
48
+ ): Promise<boolean> => {
49
+ const method = requireMethod(
50
+ getModule().setReleaseCatalogCache,
51
+ "setReleaseCatalogCache",
52
+ );
53
+
54
+ try {
55
+ return await method.call(HotUpdaterNative, partition, payload);
56
+ } catch {
57
+ return false;
58
+ }
59
+ };
60
+
61
+ export const removeNativeReleaseCatalogCache = async (
62
+ partition: string,
63
+ ): Promise<void> => {
64
+ const method = requireMethod(
65
+ getModule().removeReleaseCatalogCache,
66
+ "removeReleaseCatalogCache",
67
+ );
68
+
69
+ try {
70
+ await method.call(HotUpdaterNative, partition);
71
+ } catch {
72
+ // Cache maintenance must not prevent a network update check.
73
+ }
74
+ };