@hot-updater/react-native 0.30.12 → 0.31.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.
- package/HotUpdater.podspec +1 -0
- package/android/build.gradle +1 -0
- package/android/src/main/java/com/hotupdater/BsdiffPatch.kt +284 -0
- package/android/src/main/java/com/hotupdater/BundleFileStorageService.kt +885 -5
- package/android/src/main/java/com/hotupdater/HotUpdaterImpl.kt +13 -2
- package/android/src/main/java/com/hotupdater/OkHttpDownloadService.kt +37 -8
- package/android/src/main/java/com/hotupdater/ReactNativeValueConverters.kt +48 -12
- package/android/src/main/java/com/hotupdater/SignatureVerifier.kt +60 -22
- package/android/src/newarch/HotUpdater.kt +14 -2
- package/android/src/newarch/HotUpdaterModule.kt +112 -1
- package/android/src/oldarch/HotUpdater.kt +14 -2
- package/android/src/oldarch/HotUpdaterModule.kt +107 -3
- package/android/src/test/java/com/hotupdater/BsdiffPatchTest.kt +46 -0
- package/android/src/test/java/com/hotupdater/BundleFileStorageServiceTest.kt +29 -1
- package/android/src/test/java/com/hotupdater/HotUpdaterImplTest.kt +4 -1
- package/ios/HotUpdater/Internal/BsdiffPatchBridge.h +16 -0
- package/ios/HotUpdater/Internal/BsdiffPatchBridge.mm +343 -0
- package/ios/HotUpdater/Internal/BundleFileStorageService.swift +1093 -47
- package/ios/HotUpdater/Internal/HotUpdater-Bridging-Header.h +2 -0
- package/ios/HotUpdater/Internal/HotUpdater.mm +12 -2
- package/ios/HotUpdater/Internal/HotUpdaterImpl.swift +64 -5
- package/ios/HotUpdater/Internal/NotificationExtension.swift +2 -1
- package/ios/HotUpdater/Internal/SignatureVerifier.swift +28 -5
- package/ios/HotUpdater/Internal/StreamingTarArchiveExtractor.swift +11 -0
- package/ios/HotUpdater/Internal/URLSessionDownloadService.swift +11 -5
- package/lib/commonjs/DefaultResolver.js +6 -2
- package/lib/commonjs/DefaultResolver.js.map +1 -1
- package/lib/commonjs/DefaultResolver.spec.js +79 -3
- package/lib/commonjs/DefaultResolver.spec.js.map +1 -1
- package/lib/commonjs/checkForUpdate.js +6 -0
- package/lib/commonjs/checkForUpdate.js.map +1 -1
- package/lib/commonjs/index.js +53 -18
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.spec.js +117 -1
- package/lib/commonjs/index.spec.js.map +1 -1
- package/lib/commonjs/native.js +40 -16
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/native.spec.js +119 -3
- package/lib/commonjs/native.spec.js.map +1 -1
- package/lib/commonjs/sdkVersion.js +8 -0
- package/lib/commonjs/sdkVersion.js.map +1 -0
- package/lib/commonjs/specs/NativeHotUpdater.js.map +1 -1
- package/lib/commonjs/store.js +72 -5
- package/lib/commonjs/store.js.map +1 -1
- package/lib/commonjs/store.spec.js +265 -8
- package/lib/commonjs/store.spec.js.map +1 -1
- package/lib/commonjs/wrap.js +19 -5
- package/lib/commonjs/wrap.js.map +1 -1
- package/lib/commonjs/wrap.spec.js +74 -0
- package/lib/commonjs/wrap.spec.js.map +1 -1
- package/lib/module/DefaultResolver.js +6 -2
- package/lib/module/DefaultResolver.js.map +1 -1
- package/lib/module/DefaultResolver.spec.js +78 -3
- package/lib/module/DefaultResolver.spec.js.map +1 -1
- package/lib/module/checkForUpdate.js +6 -0
- package/lib/module/checkForUpdate.js.map +1 -1
- package/lib/module/index.js +53 -18
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.spec.js +117 -1
- package/lib/module/index.spec.js.map +1 -1
- package/lib/module/native.js +40 -16
- package/lib/module/native.js.map +1 -1
- package/lib/module/native.spec.js +119 -3
- package/lib/module/native.spec.js.map +1 -1
- package/lib/module/sdkVersion.js +4 -0
- package/lib/module/sdkVersion.js.map +1 -0
- package/lib/module/specs/NativeHotUpdater.js.map +1 -1
- package/lib/module/store.js +72 -5
- package/lib/module/store.js.map +1 -1
- package/lib/module/store.spec.js +265 -8
- package/lib/module/store.spec.js.map +1 -1
- package/lib/module/wrap.js +19 -5
- package/lib/module/wrap.js.map +1 -1
- package/lib/module/wrap.spec.js +74 -0
- package/lib/module/wrap.spec.js.map +1 -1
- package/lib/typescript/commonjs/DefaultResolver.d.ts.map +1 -1
- package/lib/typescript/commonjs/checkForUpdate.d.ts +2 -2
- package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +36 -8
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/native.d.ts +56 -3
- package/lib/typescript/commonjs/native.d.ts.map +1 -1
- package/lib/typescript/commonjs/sdkVersion.d.ts +2 -0
- package/lib/typescript/commonjs/sdkVersion.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts +27 -0
- package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts.map +1 -1
- package/lib/typescript/commonjs/store.d.ts +5 -0
- package/lib/typescript/commonjs/store.d.ts.map +1 -1
- package/lib/typescript/commonjs/wrap.d.ts +43 -29
- package/lib/typescript/commonjs/wrap.d.ts.map +1 -1
- package/lib/typescript/module/DefaultResolver.d.ts.map +1 -1
- package/lib/typescript/module/checkForUpdate.d.ts +2 -2
- package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +36 -8
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/native.d.ts +56 -3
- package/lib/typescript/module/native.d.ts.map +1 -1
- package/lib/typescript/module/sdkVersion.d.ts +2 -0
- package/lib/typescript/module/sdkVersion.d.ts.map +1 -0
- package/lib/typescript/module/specs/NativeHotUpdater.d.ts +27 -0
- package/lib/typescript/module/specs/NativeHotUpdater.d.ts.map +1 -1
- package/lib/typescript/module/store.d.ts +5 -0
- package/lib/typescript/module/store.d.ts.map +1 -1
- package/lib/typescript/module/wrap.d.ts +43 -29
- package/lib/typescript/module/wrap.d.ts.map +1 -1
- package/package.json +20 -10
- package/src/DefaultResolver.spec.ts +103 -3
- package/src/DefaultResolver.ts +9 -2
- package/src/checkForUpdate.ts +9 -2
- package/src/index.spec.ts +149 -1
- package/src/index.ts +99 -40
- package/src/native.spec.ts +139 -1
- package/src/native.ts +145 -31
- package/src/sdkVersion.ts +1 -0
- package/src/specs/NativeHotUpdater.ts +28 -0
- package/src/store.spec.ts +324 -9
- package/src/store.ts +133 -7
- package/src/wrap.spec.ts +91 -0
- package/src/wrap.tsx +79 -42
package/src/wrap.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
notifyAppReady as nativeNotifyAppReady,
|
|
10
10
|
reload,
|
|
11
11
|
} from "./native";
|
|
12
|
-
import { useHotUpdaterStore } from "./store";
|
|
12
|
+
import { type HotUpdaterState, useHotUpdaterStore } from "./store";
|
|
13
13
|
import type { HotUpdaterBaseURL, HotUpdaterResolver } from "./types";
|
|
14
14
|
|
|
15
15
|
export interface RunUpdateProcessResponse {
|
|
@@ -24,8 +24,18 @@ type UpdateStatus =
|
|
|
24
24
|
| "UPDATING"
|
|
25
25
|
| "UPDATE_PROCESS_COMPLETED";
|
|
26
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
|
+
|
|
27
37
|
/**
|
|
28
|
-
* Common options shared
|
|
38
|
+
* Common options shared by HotUpdater initialization APIs.
|
|
29
39
|
*/
|
|
30
40
|
interface CommonHotUpdaterOptions {
|
|
31
41
|
/**
|
|
@@ -51,18 +61,24 @@ interface CommonHotUpdaterOptions {
|
|
|
51
61
|
*
|
|
52
62
|
* @example
|
|
53
63
|
* ```tsx
|
|
54
|
-
* HotUpdater.
|
|
64
|
+
* HotUpdater.init({
|
|
55
65
|
* baseURL: "https://api.example.com",
|
|
56
|
-
* updateMode: "manual",
|
|
57
66
|
* onNotifyAppReady: ({ status, crashedBundleId }) => {
|
|
58
67
|
* if (status === "RECOVERED") {
|
|
59
68
|
* analytics.track("bundle_rollback", { crashedBundleId });
|
|
60
69
|
* }
|
|
61
|
-
* }
|
|
62
|
-
* })
|
|
70
|
+
* },
|
|
71
|
+
* });
|
|
63
72
|
* ```
|
|
64
73
|
*/
|
|
65
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;
|
|
66
82
|
}
|
|
67
83
|
|
|
68
84
|
/**
|
|
@@ -105,6 +121,11 @@ type NetworkConfig = BaseURLConfig | ResolverConfig;
|
|
|
105
121
|
|
|
106
122
|
export type AutoUpdateOptions = CommonHotUpdaterOptions &
|
|
107
123
|
NetworkConfig & {
|
|
124
|
+
/**
|
|
125
|
+
* Automatic update mode. This is the default and can be omitted.
|
|
126
|
+
*/
|
|
127
|
+
updateMode?: "auto";
|
|
128
|
+
|
|
108
129
|
/**
|
|
109
130
|
* Update strategy
|
|
110
131
|
* - "fingerprint": Use fingerprint hash to check for updates
|
|
@@ -112,14 +133,6 @@ export type AutoUpdateOptions = CommonHotUpdaterOptions &
|
|
|
112
133
|
*/
|
|
113
134
|
updateStrategy: "fingerprint" | "appVersion";
|
|
114
135
|
|
|
115
|
-
/**
|
|
116
|
-
* Update mode
|
|
117
|
-
* - "auto": Automatically check and download updates
|
|
118
|
-
*/
|
|
119
|
-
updateMode: "auto";
|
|
120
|
-
|
|
121
|
-
onError?: (error: HotUpdaterError | Error | unknown) => void;
|
|
122
|
-
|
|
123
136
|
/**
|
|
124
137
|
* Component to show while downloading a new bundle update.
|
|
125
138
|
*
|
|
@@ -142,11 +155,7 @@ export type AutoUpdateOptions = CommonHotUpdaterOptions &
|
|
|
142
155
|
*
|
|
143
156
|
* If not defined, the bundle will download in the background without blocking the screen.
|
|
144
157
|
*/
|
|
145
|
-
fallbackComponent?: React.FC<
|
|
146
|
-
status: Exclude<UpdateStatus, "UPDATE_PROCESS_COMPLETED">;
|
|
147
|
-
progress: number;
|
|
148
|
-
message: string | null;
|
|
149
|
-
}>;
|
|
158
|
+
fallbackComponent?: React.FC<HotUpdaterFallbackComponentProps>;
|
|
150
159
|
|
|
151
160
|
onProgress?: (progress: number) => void;
|
|
152
161
|
|
|
@@ -169,21 +178,25 @@ export type AutoUpdateOptions = CommonHotUpdaterOptions &
|
|
|
169
178
|
export type ManualUpdateOptions = CommonHotUpdaterOptions &
|
|
170
179
|
NetworkConfig & {
|
|
171
180
|
/**
|
|
172
|
-
*
|
|
173
|
-
*
|
|
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
|
|
174
195
|
*/
|
|
175
196
|
updateMode: "manual";
|
|
176
197
|
};
|
|
177
198
|
|
|
178
|
-
type
|
|
179
|
-
BaseURLConfig & {
|
|
180
|
-
updateMode: "manual";
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
export type HotUpdaterInitOptions = Omit<
|
|
184
|
-
ManualBaseURLUpdateOptions,
|
|
185
|
-
"updateMode"
|
|
186
|
-
>;
|
|
199
|
+
export type HotUpdaterInitOptions = CommonHotUpdaterOptions & NetworkConfig;
|
|
187
200
|
|
|
188
201
|
export type HotUpdaterOptions = AutoUpdateOptions | ManualUpdateOptions;
|
|
189
202
|
|
|
@@ -196,17 +209,13 @@ type InternalCommonOptions = {
|
|
|
196
209
|
requestHeaders?: Record<string, string>;
|
|
197
210
|
requestTimeout?: number;
|
|
198
211
|
onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
|
|
212
|
+
onError?: (error: HotUpdaterError | Error | unknown) => void;
|
|
199
213
|
};
|
|
200
214
|
|
|
201
215
|
type InternalAutoUpdateOptions = InternalCommonOptions & {
|
|
202
216
|
updateStrategy: "fingerprint" | "appVersion";
|
|
203
217
|
updateMode: "auto";
|
|
204
|
-
|
|
205
|
-
fallbackComponent?: React.FC<{
|
|
206
|
-
status: Exclude<UpdateStatus, "UPDATE_PROCESS_COMPLETED">;
|
|
207
|
-
progress: number;
|
|
208
|
-
message: string | null;
|
|
209
|
-
}>;
|
|
218
|
+
fallbackComponent?: React.FC<HotUpdaterFallbackComponentProps>;
|
|
210
219
|
onProgress?: (progress: number) => void;
|
|
211
220
|
reloadOnForceUpdate?: boolean;
|
|
212
221
|
onUpdateProcessCompleted?: (response: RunUpdateProcessResponse) => void;
|
|
@@ -224,6 +233,23 @@ export type InternalWrapOptions =
|
|
|
224
233
|
|
|
225
234
|
type RequestAnimationFrame = (callback: (timestamp: number) => void) => number;
|
|
226
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
|
+
|
|
227
253
|
const waitForNextFrame = () =>
|
|
228
254
|
new Promise<void>((resolve) => {
|
|
229
255
|
const requestAnimationFrame = (
|
|
@@ -248,6 +274,7 @@ const handleNotifyAppReady = async (options: {
|
|
|
248
274
|
requestHeaders?: Record<string, string>;
|
|
249
275
|
requestTimeout?: number;
|
|
250
276
|
onNotifyAppReady?: (result: NotifyAppReadyResult) => void;
|
|
277
|
+
onError?: (error: HotUpdaterError | Error | unknown) => void;
|
|
251
278
|
}): Promise<void> => {
|
|
252
279
|
await waitForNextFrame();
|
|
253
280
|
|
|
@@ -264,12 +291,14 @@ const handleNotifyAppReady = async (options: {
|
|
|
264
291
|
requestTimeout: options.requestTimeout,
|
|
265
292
|
})
|
|
266
293
|
.catch((e: unknown) => {
|
|
294
|
+
options.onError?.(e);
|
|
267
295
|
console.warn("[HotUpdater] Resolver notifyAppReady failed:", e);
|
|
268
296
|
});
|
|
269
297
|
}
|
|
270
298
|
|
|
271
299
|
options.onNotifyAppReady?.(nativeResult);
|
|
272
300
|
} catch (e) {
|
|
301
|
+
options.onError?.(e);
|
|
273
302
|
console.warn("[HotUpdater] Failed to notify app ready:", e);
|
|
274
303
|
}
|
|
275
304
|
};
|
|
@@ -278,11 +307,15 @@ export function init(options: InternalInitOptions): void {
|
|
|
278
307
|
void handleNotifyAppReady(options);
|
|
279
308
|
}
|
|
280
309
|
|
|
281
|
-
export function wrap
|
|
310
|
+
export function wrap(
|
|
282
311
|
options: InternalWrapOptions,
|
|
283
|
-
):
|
|
312
|
+
): <P extends object>(
|
|
313
|
+
WrappedComponent: React.ComponentType<P>,
|
|
314
|
+
) => React.ComponentType<P> {
|
|
284
315
|
if (options.updateMode === "manual") {
|
|
285
|
-
|
|
316
|
+
warnManualWrapDeprecation();
|
|
317
|
+
|
|
318
|
+
return <P extends object>(WrappedComponent: React.ComponentType<P>) => {
|
|
286
319
|
const ManualHOC: React.FC<P> = (props: P) => {
|
|
287
320
|
useEffect(() => {
|
|
288
321
|
void handleNotifyAppReady(options);
|
|
@@ -295,12 +328,12 @@ export function wrap<P extends React.JSX.IntrinsicAttributes = object>(
|
|
|
295
328
|
};
|
|
296
329
|
}
|
|
297
330
|
|
|
298
|
-
// updateMode: "auto"
|
|
299
331
|
const { reloadOnForceUpdate = true, ...restOptions } = options;
|
|
300
332
|
|
|
301
|
-
return (WrappedComponent: React.ComponentType<P>) => {
|
|
333
|
+
return <P extends object>(WrappedComponent: React.ComponentType<P>) => {
|
|
302
334
|
const HotUpdaterHOC: React.FC<P> = (props: P) => {
|
|
303
|
-
const
|
|
335
|
+
const progressState = useHotUpdaterStore((state) => state);
|
|
336
|
+
const progress = progressState.progress;
|
|
304
337
|
|
|
305
338
|
const [message, setMessage] = useState<string | null>(null);
|
|
306
339
|
const [updateStatus, setUpdateStatus] =
|
|
@@ -394,9 +427,13 @@ export function wrap<P extends React.JSX.IntrinsicAttributes = object>(
|
|
|
394
427
|
const Fallback = restOptions.fallbackComponent;
|
|
395
428
|
return (
|
|
396
429
|
<Fallback
|
|
430
|
+
artifactType={progressState.artifactType}
|
|
431
|
+
details={progressState.details}
|
|
432
|
+
downloadedBytes={progressState.downloadedBytes}
|
|
397
433
|
progress={progress}
|
|
398
434
|
status={updateStatus}
|
|
399
435
|
message={message}
|
|
436
|
+
totalBytes={progressState.totalBytes}
|
|
400
437
|
/>
|
|
401
438
|
);
|
|
402
439
|
}
|