@hot-updater/react-native 0.36.7 → 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.
- package/android/src/main/java/com/hotupdater/BundleFileStorageService.kt +357 -6
- package/android/src/main/java/com/hotupdater/BundleMetadata.kt +268 -34
- package/android/src/main/java/com/hotupdater/HotUpdaterImpl.kt +75 -9
- package/android/src/main/java/com/hotupdater/NativeConfigUtils.kt +2 -16
- package/android/src/main/java/com/hotupdater/ReleaseCatalogCacheService.kt +166 -0
- package/android/src/main/java/com/hotupdater/SignatureVerifier.kt +1 -2
- package/android/src/newarch/HotUpdater.kt +1 -1
- package/android/src/newarch/HotUpdaterModule.kt +116 -0
- package/android/src/oldarch/HotUpdater.kt +1 -1
- package/android/src/oldarch/HotUpdaterModule.kt +128 -0
- package/android/src/oldarch/HotUpdaterSpec.kt +38 -0
- package/android/src/test/java/com/hotupdater/BundleFileStorageServiceTest.kt +280 -2
- package/android/src/test/java/com/hotupdater/HotUpdaterImplTest.kt +57 -2
- package/android/src/test/java/com/hotupdater/ReleaseCatalogCacheServiceTest.kt +118 -0
- package/ios/HotUpdater/Internal/BundleFileStorageService.swift +491 -30
- package/ios/HotUpdater/Internal/BundleMetadata.swift +229 -6
- package/ios/HotUpdater/Internal/HotUpdater.mm +122 -0
- package/ios/HotUpdater/Internal/HotUpdaterImpl.swift +176 -7
- package/ios/HotUpdater/Internal/ReleaseCatalogCacheService.swift +213 -0
- package/lib/commonjs/catalogCacheNative.js +44 -0
- package/lib/commonjs/catalogCacheNative.js.map +1 -0
- package/lib/commonjs/catalogCacheNative.spec.js +31 -0
- package/lib/commonjs/catalogCacheNative.spec.js.map +1 -0
- package/lib/commonjs/checkForUpdate.js +231 -60
- package/lib/commonjs/checkForUpdate.js.map +1 -1
- package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js +604 -0
- package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js.map +1 -0
- package/lib/commonjs/error.js +8 -1
- package/lib/commonjs/error.js.map +1 -1
- package/lib/commonjs/{fetchUpdateInfo.js → fetchJSON.js} +11 -14
- package/lib/commonjs/fetchJSON.js.map +1 -0
- package/lib/commonjs/httpClient.js +153 -0
- package/lib/commonjs/httpClient.js.map +1 -0
- package/lib/commonjs/httpClient.spec.js +102 -0
- package/lib/commonjs/httpClient.spec.js.map +1 -0
- package/lib/commonjs/index.js +48 -71
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.spec.js +117 -161
- package/lib/commonjs/index.spec.js.map +1 -1
- package/lib/commonjs/iosInterop.spec.js +18 -0
- package/lib/commonjs/iosInterop.spec.js.map +1 -0
- package/lib/commonjs/native.js +222 -55
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/native.spec.js +226 -12
- package/lib/commonjs/native.spec.js.map +1 -1
- package/lib/commonjs/notifyAppReadyAnalytics.boundary.spec.js +218 -0
- package/lib/commonjs/notifyAppReadyAnalytics.boundary.spec.js.map +1 -0
- package/lib/commonjs/notifyAppReadyAnalytics.js +133 -0
- package/lib/commonjs/notifyAppReadyAnalytics.js.map +1 -0
- package/lib/commonjs/notifyAppReadyAnalytics.spec.js +246 -0
- package/lib/commonjs/notifyAppReadyAnalytics.spec.js.map +1 -0
- package/lib/commonjs/notifyAppReadyAnalytics.test-utils.js +24 -0
- package/lib/commonjs/notifyAppReadyAnalytics.test-utils.js.map +1 -0
- package/lib/commonjs/notifyAppReadyAnalytics.transport.spec.js +117 -0
- package/lib/commonjs/notifyAppReadyAnalytics.transport.spec.js.map +1 -0
- package/lib/commonjs/releaseCatalogCache.js +179 -0
- package/lib/commonjs/releaseCatalogCache.js.map +1 -0
- package/lib/commonjs/releaseCatalogCache.spec.js +195 -0
- package/lib/commonjs/releaseCatalogCache.spec.js.map +1 -0
- package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js +64 -0
- package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js.map +1 -0
- package/lib/commonjs/sdkVersion.js +1 -1
- package/lib/commonjs/sdkVersion.js.map +1 -1
- package/lib/commonjs/specs/NativeHotUpdater.js.map +1 -1
- package/lib/commonjs/types.js +0 -12
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/wrap.js +7 -82
- package/lib/commonjs/wrap.js.map +1 -1
- package/lib/commonjs/wrap.spec.js +203 -56
- package/lib/commonjs/wrap.spec.js.map +1 -1
- package/lib/commonjs/wrap.types.js +6 -0
- package/lib/commonjs/wrap.types.js.map +1 -0
- package/lib/module/catalogCacheNative.js +36 -0
- package/lib/module/catalogCacheNative.js.map +1 -0
- package/lib/module/catalogCacheNative.spec.js +31 -0
- package/lib/module/catalogCacheNative.spec.js.map +1 -0
- package/lib/module/checkForUpdate.js +233 -62
- package/lib/module/checkForUpdate.js.map +1 -1
- package/lib/module/checkForUpdate.releaseCatalog.spec.js +603 -0
- package/lib/module/checkForUpdate.releaseCatalog.spec.js.map +1 -0
- package/lib/module/error.js +6 -0
- package/lib/module/error.js.map +1 -1
- package/lib/module/{fetchUpdateInfo.js → fetchJSON.js} +9 -12
- package/lib/module/fetchJSON.js.map +1 -0
- package/lib/module/httpClient.js +148 -0
- package/lib/module/httpClient.js.map +1 -0
- package/lib/module/httpClient.spec.js +102 -0
- package/lib/module/httpClient.spec.js.map +1 -0
- package/lib/module/index.js +49 -66
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.spec.js +117 -161
- package/lib/module/index.spec.js.map +1 -1
- package/lib/module/iosInterop.spec.js +18 -0
- package/lib/module/iosInterop.spec.js.map +1 -0
- package/lib/module/native.js +206 -51
- package/lib/module/native.js.map +1 -1
- package/lib/module/native.spec.js +226 -12
- package/lib/module/native.spec.js.map +1 -1
- package/lib/module/notifyAppReadyAnalytics.boundary.spec.js +217 -0
- package/lib/module/notifyAppReadyAnalytics.boundary.spec.js.map +1 -0
- package/lib/module/notifyAppReadyAnalytics.js +128 -0
- package/lib/module/notifyAppReadyAnalytics.js.map +1 -0
- package/lib/module/notifyAppReadyAnalytics.spec.js +245 -0
- package/lib/module/notifyAppReadyAnalytics.spec.js.map +1 -0
- package/lib/module/notifyAppReadyAnalytics.test-utils.js +18 -0
- package/lib/module/notifyAppReadyAnalytics.test-utils.js.map +1 -0
- package/lib/module/notifyAppReadyAnalytics.transport.spec.js +116 -0
- package/lib/module/notifyAppReadyAnalytics.transport.spec.js.map +1 -0
- package/lib/module/releaseCatalogCache.js +171 -0
- package/lib/module/releaseCatalogCache.js.map +1 -0
- package/lib/module/releaseCatalogCache.spec.js +195 -0
- package/lib/module/releaseCatalogCache.spec.js.map +1 -0
- package/lib/module/releaseCatalogCacheNativeContract.spec.js +64 -0
- package/lib/module/releaseCatalogCacheNativeContract.spec.js.map +1 -0
- package/lib/module/sdkVersion.js +1 -1
- package/lib/module/sdkVersion.js.map +1 -1
- package/lib/module/specs/NativeHotUpdater.js.map +1 -1
- package/lib/module/types.js +0 -12
- package/lib/module/types.js.map +1 -1
- package/lib/module/wrap.js +6 -81
- package/lib/module/wrap.js.map +1 -1
- package/lib/module/wrap.spec.js +203 -56
- package/lib/module/wrap.spec.js.map +1 -1
- package/lib/module/wrap.types.js +4 -0
- package/lib/module/wrap.types.js.map +1 -0
- package/lib/typescript/commonjs/catalogCacheNative.d.ts +4 -0
- package/lib/typescript/commonjs/catalogCacheNative.d.ts.map +1 -0
- package/lib/typescript/commonjs/checkForUpdate.d.ts +14 -4
- package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/commonjs/error.d.ts +3 -0
- package/lib/typescript/commonjs/error.d.ts.map +1 -1
- package/lib/typescript/commonjs/fetchJSON.d.ts +6 -0
- package/lib/typescript/commonjs/fetchJSON.d.ts.map +1 -0
- package/lib/typescript/commonjs/httpClient.d.ts +56 -0
- package/lib/typescript/commonjs/httpClient.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +32 -41
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/native.d.ts +83 -18
- package/lib/typescript/commonjs/native.d.ts.map +1 -1
- package/lib/typescript/commonjs/notifyAppReadyAnalytics.d.ts +13 -0
- package/lib/typescript/commonjs/notifyAppReadyAnalytics.d.ts.map +1 -0
- package/lib/typescript/commonjs/notifyAppReadyAnalytics.test-utils.d.ts +8 -0
- package/lib/typescript/commonjs/notifyAppReadyAnalytics.test-utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/releaseCatalogCache.d.ts +25 -0
- package/lib/typescript/commonjs/releaseCatalogCache.d.ts.map +1 -0
- package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
- package/lib/typescript/commonjs/sdkVersion.d.ts.map +1 -1
- package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts +40 -5
- package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts.map +1 -1
- package/lib/typescript/commonjs/types.d.ts +0 -118
- package/lib/typescript/commonjs/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/wrap.d.ts +2 -191
- package/lib/typescript/commonjs/wrap.d.ts.map +1 -1
- package/lib/typescript/commonjs/wrap.types.d.ts +65 -0
- package/lib/typescript/commonjs/wrap.types.d.ts.map +1 -0
- package/lib/typescript/module/catalogCacheNative.d.ts +4 -0
- package/lib/typescript/module/catalogCacheNative.d.ts.map +1 -0
- package/lib/typescript/module/checkForUpdate.d.ts +14 -4
- package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/module/error.d.ts +3 -0
- package/lib/typescript/module/error.d.ts.map +1 -1
- package/lib/typescript/module/fetchJSON.d.ts +6 -0
- package/lib/typescript/module/fetchJSON.d.ts.map +1 -0
- package/lib/typescript/module/httpClient.d.ts +56 -0
- package/lib/typescript/module/httpClient.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +32 -41
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/native.d.ts +83 -18
- package/lib/typescript/module/native.d.ts.map +1 -1
- package/lib/typescript/module/notifyAppReadyAnalytics.d.ts +13 -0
- package/lib/typescript/module/notifyAppReadyAnalytics.d.ts.map +1 -0
- package/lib/typescript/module/notifyAppReadyAnalytics.test-utils.d.ts +8 -0
- package/lib/typescript/module/notifyAppReadyAnalytics.test-utils.d.ts.map +1 -0
- package/lib/typescript/module/releaseCatalogCache.d.ts +25 -0
- package/lib/typescript/module/releaseCatalogCache.d.ts.map +1 -0
- package/lib/typescript/module/sdkVersion.d.ts +1 -1
- package/lib/typescript/module/sdkVersion.d.ts.map +1 -1
- package/lib/typescript/module/specs/NativeHotUpdater.d.ts +40 -5
- package/lib/typescript/module/specs/NativeHotUpdater.d.ts.map +1 -1
- package/lib/typescript/module/types.d.ts +0 -118
- package/lib/typescript/module/types.d.ts.map +1 -1
- package/lib/typescript/module/wrap.d.ts +2 -191
- package/lib/typescript/module/wrap.d.ts.map +1 -1
- package/lib/typescript/module/wrap.types.d.ts +65 -0
- package/lib/typescript/module/wrap.types.d.ts.map +1 -0
- package/package.json +6 -24
- package/src/catalogCacheNative.spec.ts +63 -0
- package/src/catalogCacheNative.ts +74 -0
- package/src/checkForUpdate.releaseCatalog.spec.ts +596 -0
- package/src/checkForUpdate.ts +368 -97
- package/src/error.ts +7 -0
- package/src/{fetchUpdateInfo.ts → fetchJSON.ts} +8 -15
- package/src/httpClient.spec.ts +132 -0
- package/src/httpClient.ts +261 -0
- package/src/index.spec.ts +110 -203
- package/src/index.ts +70 -93
- package/src/iosInterop.spec.ts +30 -0
- package/src/native.spec.ts +226 -10
- package/src/native.ts +385 -83
- package/src/notifyAppReadyAnalytics.boundary.spec.ts +234 -0
- package/src/notifyAppReadyAnalytics.spec.ts +243 -0
- package/src/notifyAppReadyAnalytics.test-utils.ts +31 -0
- package/src/notifyAppReadyAnalytics.transport.spec.ts +130 -0
- package/src/notifyAppReadyAnalytics.ts +194 -0
- package/src/releaseCatalogCache.spec.ts +282 -0
- package/src/releaseCatalogCache.ts +341 -0
- package/src/releaseCatalogCacheNativeContract.spec.ts +80 -0
- package/src/sdkVersion.ts +1 -1
- package/src/specs/NativeHotUpdater.ts +51 -5
- package/src/types.ts +0 -140
- package/src/wrap.spec.ts +251 -56
- package/src/wrap.tsx +23 -318
- package/src/wrap.types.ts +78 -0
- package/android/src/main/java/com/hotupdater/StringResourceUtils.kt +0 -45
- package/app.plugin.js +0 -1
- package/ios/HotUpdater/Internal/HotUpdaterCrashHandler.h +0 -7
- package/ios/HotUpdater/Internal/HotUpdaterCrashHandler.mm +0 -4
- package/lib/commonjs/DefaultResolver.js +0 -50
- package/lib/commonjs/DefaultResolver.js.map +0 -1
- package/lib/commonjs/DefaultResolver.spec.js +0 -144
- package/lib/commonjs/DefaultResolver.spec.js.map +0 -1
- package/lib/commonjs/fetchUpdateInfo.js.map +0 -1
- package/lib/module/DefaultResolver.js +0 -46
- package/lib/module/DefaultResolver.js.map +0 -1
- package/lib/module/DefaultResolver.spec.js +0 -144
- package/lib/module/DefaultResolver.spec.js.map +0 -1
- package/lib/module/fetchUpdateInfo.js.map +0 -1
- package/lib/typescript/commonjs/DefaultResolver.d.ts +0 -11
- package/lib/typescript/commonjs/DefaultResolver.d.ts.map +0 -1
- package/lib/typescript/commonjs/fetchUpdateInfo.d.ts +0 -7
- package/lib/typescript/commonjs/fetchUpdateInfo.d.ts.map +0 -1
- package/lib/typescript/module/DefaultResolver.d.ts +0 -11
- package/lib/typescript/module/DefaultResolver.d.ts.map +0 -1
- package/lib/typescript/module/fetchUpdateInfo.d.ts +0 -7
- package/lib/typescript/module/fetchUpdateInfo.d.ts.map +0 -1
- package/plugin/build/transformers.js +0 -314
- package/plugin/build/withHotUpdater.js +0 -228
- package/src/DefaultResolver.spec.ts +0 -193
- 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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,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":[]}
|