@hot-updater/react-native 0.25.13 → 0.26.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 +42 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterImpl.kt +25 -0
- package/android/src/newarch/HotUpdater.kt +4 -1
- package/android/src/newarch/HotUpdaterModule.kt +18 -1
- package/android/src/oldarch/HotUpdater.kt +4 -1
- package/android/src/oldarch/HotUpdaterModule.kt +19 -1
- package/android/src/oldarch/HotUpdaterSpec.kt +2 -0
- package/ios/HotUpdater/Internal/BundleFileStorageService.swift +44 -0
- package/ios/HotUpdater/Internal/HotUpdater.mm +17 -0
- package/ios/HotUpdater/Internal/HotUpdaterImpl.swift +44 -2
- package/lib/commonjs/checkForUpdate.js +29 -4
- package/lib/commonjs/checkForUpdate.js.map +1 -1
- package/lib/commonjs/index.js +35 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/native.js +88 -21
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/specs/NativeHotUpdater.js.map +1 -1
- package/lib/module/checkForUpdate.js +29 -5
- package/lib/module/checkForUpdate.js.map +1 -1
- package/lib/module/index.js +36 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/native.js +81 -16
- package/lib/module/native.js.map +1 -1
- package/lib/module/specs/NativeHotUpdater.js.map +1 -1
- package/lib/typescript/commonjs/checkForUpdate.d.ts +5 -0
- package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +26 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/native.d.ts +13 -0
- package/lib/typescript/commonjs/native.d.ts.map +1 -1
- package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts +8 -0
- package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts.map +1 -1
- package/lib/typescript/module/checkForUpdate.d.ts +5 -0
- package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +26 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/native.d.ts +13 -0
- package/lib/typescript/module/native.d.ts.map +1 -1
- package/lib/typescript/module/specs/NativeHotUpdater.d.ts +8 -0
- package/lib/typescript/module/specs/NativeHotUpdater.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/checkForUpdate.ts +63 -3
- package/src/index.ts +41 -0
- package/src/native.ts +103 -16
- package/src/specs/NativeHotUpdater.ts +9 -0
|
@@ -79,6 +79,25 @@ export declare const HotUpdater: {
|
|
|
79
79
|
* ```
|
|
80
80
|
*/
|
|
81
81
|
getChannel: () => string;
|
|
82
|
+
/**
|
|
83
|
+
* Fetches the build-time default channel of the app.
|
|
84
|
+
*
|
|
85
|
+
* This value does not change when a runtime channel override is active.
|
|
86
|
+
*
|
|
87
|
+
* @returns {string} The default release channel embedded in the app
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* const defaultChannel = HotUpdater.getDefaultChannel();
|
|
91
|
+
* console.log(`Default channel: ${defaultChannel}`);
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
getDefaultChannel: () => string;
|
|
95
|
+
/**
|
|
96
|
+
* Returns whether the app is currently using a runtime channel override.
|
|
97
|
+
*
|
|
98
|
+
* @returns {boolean} true when a non-default channel has been applied
|
|
99
|
+
*/
|
|
100
|
+
isChannelSwitched: () => boolean;
|
|
82
101
|
/**
|
|
83
102
|
* Adds a listener to HotUpdater events.
|
|
84
103
|
*
|
|
@@ -102,6 +121,7 @@ export declare const HotUpdater: {
|
|
|
102
121
|
*
|
|
103
122
|
* @param {Object} config - Update check configuration
|
|
104
123
|
* @param {string} config.source - Update server URL
|
|
124
|
+
* @param {string} [config.channel] - Optional channel override for this update check
|
|
105
125
|
* @param {Record<string, string>} [config.requestHeaders] - Request headers
|
|
106
126
|
*
|
|
107
127
|
* @returns {Promise<UpdateInfo | null>} Update information or null if up to date
|
|
@@ -161,6 +181,12 @@ export declare const HotUpdater: {
|
|
|
161
181
|
* ```
|
|
162
182
|
*/
|
|
163
183
|
updateBundle: (params: UpdateParams) => Promise<boolean>;
|
|
184
|
+
/**
|
|
185
|
+
* Clears the runtime channel override and restores the original bundle.
|
|
186
|
+
*
|
|
187
|
+
* @returns {Promise<boolean>} Resolves with true if reset was successful
|
|
188
|
+
*/
|
|
189
|
+
resetChannel: () => Promise<boolean>;
|
|
164
190
|
/**
|
|
165
191
|
* Fetches the fingerprint of the app.
|
|
166
192
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAG3B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAG3B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAcL,KAAK,YAAY,EAElB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,KAAK,iBAAiB,EAAkC,MAAM,QAAQ,CAAC;AAEhF,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACtE,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,4BAA4B,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,GAClC,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,QAAQ,CAAC;AA4W1E,eAAO,MAAM,UAAU;IA5SnB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;oBACa,iBAAiB;IAuCjC;;OAEG;;IAGH;;;;;;;;;;;;;;;;OAgBG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;;;;;;;;;;;OAYG;;IAGH;;;;;;;;;;;OAWG;;IAGH;;;;OAIG;;IAGH;;;;;;;;;;;;;;;;OAgBG;;IAGH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;6BACsB,qBAAqB;IAgB9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;2BACoB,YAAY;IAKnC;;;;OAIG;;IAYH;;;;;;;;;;OAUG;;IAGH;;;;;;;;;;;OAWG;;IAGH;;;;;;;;;;;OAWG;;CAK2C,CAAC"}
|
|
@@ -13,6 +13,7 @@ export type HotUpdaterEvent = {
|
|
|
13
13
|
export declare const addListener: <T extends keyof HotUpdaterEvent>(eventName: T, listener: (event: HotUpdaterEvent[T]) => void) => () => void;
|
|
14
14
|
export type UpdateParams = UpdateBundleParams & {
|
|
15
15
|
status: UpdateStatus;
|
|
16
|
+
shouldSkipCurrentBundleIdCheck?: boolean;
|
|
16
17
|
};
|
|
17
18
|
/**
|
|
18
19
|
* Downloads files and applies them to the app.
|
|
@@ -54,6 +55,14 @@ export declare const getBundleId: () => string;
|
|
|
54
55
|
* @returns {string} Resolves with the channel or null if not available.
|
|
55
56
|
*/
|
|
56
57
|
export declare const getChannel: () => string;
|
|
58
|
+
/**
|
|
59
|
+
* Fetches the build-time default channel for the app.
|
|
60
|
+
*/
|
|
61
|
+
export declare const getDefaultChannel: () => string;
|
|
62
|
+
/**
|
|
63
|
+
* Returns whether the app is currently using a runtime channel override.
|
|
64
|
+
*/
|
|
65
|
+
export declare const isChannelSwitched: () => boolean;
|
|
57
66
|
/**
|
|
58
67
|
* Fetches the fingerprint for the app.
|
|
59
68
|
*
|
|
@@ -121,4 +130,8 @@ export declare const clearCrashHistory: () => boolean;
|
|
|
121
130
|
* @returns {string | null} Base URL string (e.g., "file:///data/.../bundle-store/abc123") or null if not available
|
|
122
131
|
*/
|
|
123
132
|
export declare const getBaseURL: () => string | null;
|
|
133
|
+
/**
|
|
134
|
+
* Clears the runtime channel override and restores the original bundle.
|
|
135
|
+
*/
|
|
136
|
+
export declare const resetChannel: () => Promise<boolean>;
|
|
124
137
|
//# sourceMappingURL=native.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../src/native.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjE,OAAyB,EACvB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;AAMlD,eAAO,MAAM,mBAAmB;;CAE/B,CAAC;
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../src/native.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjE,OAAyB,EACvB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;AAMlD,eAAO,MAAM,mBAAmB;;CAE/B,CAAC;AA0DF,MAAM,MAAM,eAAe,GAAG;IAC5B,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAIF,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,eAAe,EACzD,WAAW,CAAC,EACZ,UAAU,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,eAO9C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG;IAC9C,MAAM,EAAE,YAAY,CAAC;IACrB,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAC1C,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC3E;;GAEG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,OAAO,CAAC,CAAC;AAuEpB;;GAEG;AACH,eAAO,MAAM,aAAa,QAAO,MAAM,GAAG,IAGzC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,MAAM,qBAElB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,QAAO,MAGjC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,QAAO,MAI9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,QAAO,MAE7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAO,MAEpC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAO,OAEpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,QAAO,MAAM,GAAG,IAG9C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,cAAc,QAAO,oBAYjC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QAAO,MAAM,EAWxC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAAO,OAEpC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,QAAO,MAAM,GAAG,IAMtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,QAAa,OAAO,CAAC,OAAO,CAUpD,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { TurboModule } from "react-native";
|
|
2
2
|
export interface UpdateBundleParams {
|
|
3
3
|
bundleId: string;
|
|
4
|
+
channel?: string;
|
|
4
5
|
fileUrl: string | null;
|
|
5
6
|
/**
|
|
6
7
|
* File hash for integrity/signature verification.
|
|
@@ -78,6 +79,12 @@ export interface Spec extends TurboModule {
|
|
|
78
79
|
* @returns true if clearing was successful
|
|
79
80
|
*/
|
|
80
81
|
clearCrashHistory(): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Clears the runtime channel override and restores the original bundle.
|
|
84
|
+
*
|
|
85
|
+
* @returns Promise that resolves to true if successful
|
|
86
|
+
*/
|
|
87
|
+
resetChannel(): Promise<boolean>;
|
|
81
88
|
/**
|
|
82
89
|
* Gets the base URL for the current active bundle directory.
|
|
83
90
|
* Returns the file:// URL to the bundle directory without trailing slash.
|
|
@@ -92,6 +99,7 @@ export interface Spec extends TurboModule {
|
|
|
92
99
|
MIN_BUNDLE_ID: string;
|
|
93
100
|
APP_VERSION: string | null;
|
|
94
101
|
CHANNEL: string;
|
|
102
|
+
DEFAULT_CHANNEL: string;
|
|
95
103
|
FINGERPRINT_HASH: string | null;
|
|
96
104
|
};
|
|
97
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeHotUpdater.d.ts","sourceRoot":"","sources":["../../../../src/specs/NativeHotUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,IAAK,SAAQ,WAAW;IAEvC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3D;;;;;;;;;;OAUG;IACH,cAAc,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG;QAC5C,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;QAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IAEF;;;;;OAKG;IACH,eAAe,IAAI,MAAM,EAAE,CAAC;IAE5B;;;;;OAKG;IACH,iBAAiB,IAAI,OAAO,CAAC;IAE7B;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,MAAM,CAAC;IAGzB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;CACH;;AAED,wBAAoE"}
|
|
1
|
+
{"version":3,"file":"NativeHotUpdater.d.ts","sourceRoot":"","sources":["../../../../src/specs/NativeHotUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,IAAK,SAAQ,WAAW;IAEvC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3D;;;;;;;;;;OAUG;IACH,cAAc,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG;QAC5C,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;QAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IAEF;;;;;OAKG;IACH,eAAe,IAAI,MAAM,EAAE,CAAC;IAE5B;;;;;OAKG;IACH,iBAAiB,IAAI,OAAO,CAAC;IAE7B;;;;OAIG;IACH,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjC;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,MAAM,CAAC;IAGzB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;CACH;;AAED,wBAAoE"}
|
|
@@ -8,6 +8,11 @@ export interface CheckForUpdateOptions {
|
|
|
8
8
|
* - Can override the strategy set in HotUpdater.wrap()
|
|
9
9
|
*/
|
|
10
10
|
updateStrategy: "appVersion" | "fingerprint";
|
|
11
|
+
/**
|
|
12
|
+
* Override the current channel when checking for updates.
|
|
13
|
+
* The channel switch is only persisted after the returned update is applied.
|
|
14
|
+
*/
|
|
15
|
+
channel?: string;
|
|
11
16
|
requestHeaders?: Record<string, string>;
|
|
12
17
|
onError?: (error: Error) => void;
|
|
13
18
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkForUpdate.d.ts","sourceRoot":"","sources":["../../../src/checkForUpdate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"checkForUpdate.d.ts","sourceRoot":"","sources":["../../../src/checkForUpdate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAcvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAIlD,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,cAAc,EAAE,YAAY,GAAG,aAAa,CAAC;IAE7C;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG;IACjD;;;OAGG;IACH,YAAY,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACtC,CAAC;AAGF,MAAM,WAAW,6BAA8B,SAAQ,qBAAqB;IAC1E,QAAQ,EAAE,kBAAkB,CAAC;CAC9B;AAUD,wBAAsB,cAAc,CAClC,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CA2GtC"}
|
|
@@ -79,6 +79,25 @@ export declare const HotUpdater: {
|
|
|
79
79
|
* ```
|
|
80
80
|
*/
|
|
81
81
|
getChannel: () => string;
|
|
82
|
+
/**
|
|
83
|
+
* Fetches the build-time default channel of the app.
|
|
84
|
+
*
|
|
85
|
+
* This value does not change when a runtime channel override is active.
|
|
86
|
+
*
|
|
87
|
+
* @returns {string} The default release channel embedded in the app
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* const defaultChannel = HotUpdater.getDefaultChannel();
|
|
91
|
+
* console.log(`Default channel: ${defaultChannel}`);
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
getDefaultChannel: () => string;
|
|
95
|
+
/**
|
|
96
|
+
* Returns whether the app is currently using a runtime channel override.
|
|
97
|
+
*
|
|
98
|
+
* @returns {boolean} true when a non-default channel has been applied
|
|
99
|
+
*/
|
|
100
|
+
isChannelSwitched: () => boolean;
|
|
82
101
|
/**
|
|
83
102
|
* Adds a listener to HotUpdater events.
|
|
84
103
|
*
|
|
@@ -102,6 +121,7 @@ export declare const HotUpdater: {
|
|
|
102
121
|
*
|
|
103
122
|
* @param {Object} config - Update check configuration
|
|
104
123
|
* @param {string} config.source - Update server URL
|
|
124
|
+
* @param {string} [config.channel] - Optional channel override for this update check
|
|
105
125
|
* @param {Record<string, string>} [config.requestHeaders] - Request headers
|
|
106
126
|
*
|
|
107
127
|
* @returns {Promise<UpdateInfo | null>} Update information or null if up to date
|
|
@@ -161,6 +181,12 @@ export declare const HotUpdater: {
|
|
|
161
181
|
* ```
|
|
162
182
|
*/
|
|
163
183
|
updateBundle: (params: UpdateParams) => Promise<boolean>;
|
|
184
|
+
/**
|
|
185
|
+
* Clears the runtime channel override and restores the original bundle.
|
|
186
|
+
*
|
|
187
|
+
* @returns {Promise<boolean>} Resolves with true if reset was successful
|
|
188
|
+
*/
|
|
189
|
+
resetChannel: () => Promise<boolean>;
|
|
164
190
|
/**
|
|
165
191
|
* Fetches the fingerprint of the app.
|
|
166
192
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAG3B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAG3B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAcL,KAAK,YAAY,EAElB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,KAAK,iBAAiB,EAAkC,MAAM,QAAQ,CAAC;AAEhF,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACtE,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,4BAA4B,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,GAClC,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,QAAQ,CAAC;AA4W1E,eAAO,MAAM,UAAU;IA5SnB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;oBACa,iBAAiB;IAuCjC;;OAEG;;IAGH;;;;;;;;;;;;;;;;OAgBG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;;;;;;;;;;;OAYG;;IAGH;;;;;;;;;;;OAWG;;IAGH;;;;OAIG;;IAGH;;;;;;;;;;;;;;;;OAgBG;;IAGH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;6BACsB,qBAAqB;IAgB9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;2BACoB,YAAY;IAKnC;;;;OAIG;;IAYH;;;;;;;;;;OAUG;;IAGH;;;;;;;;;;;OAWG;;IAGH;;;;;;;;;;;OAWG;;CAK2C,CAAC"}
|
|
@@ -13,6 +13,7 @@ export type HotUpdaterEvent = {
|
|
|
13
13
|
export declare const addListener: <T extends keyof HotUpdaterEvent>(eventName: T, listener: (event: HotUpdaterEvent[T]) => void) => () => void;
|
|
14
14
|
export type UpdateParams = UpdateBundleParams & {
|
|
15
15
|
status: UpdateStatus;
|
|
16
|
+
shouldSkipCurrentBundleIdCheck?: boolean;
|
|
16
17
|
};
|
|
17
18
|
/**
|
|
18
19
|
* Downloads files and applies them to the app.
|
|
@@ -54,6 +55,14 @@ export declare const getBundleId: () => string;
|
|
|
54
55
|
* @returns {string} Resolves with the channel or null if not available.
|
|
55
56
|
*/
|
|
56
57
|
export declare const getChannel: () => string;
|
|
58
|
+
/**
|
|
59
|
+
* Fetches the build-time default channel for the app.
|
|
60
|
+
*/
|
|
61
|
+
export declare const getDefaultChannel: () => string;
|
|
62
|
+
/**
|
|
63
|
+
* Returns whether the app is currently using a runtime channel override.
|
|
64
|
+
*/
|
|
65
|
+
export declare const isChannelSwitched: () => boolean;
|
|
57
66
|
/**
|
|
58
67
|
* Fetches the fingerprint for the app.
|
|
59
68
|
*
|
|
@@ -121,4 +130,8 @@ export declare const clearCrashHistory: () => boolean;
|
|
|
121
130
|
* @returns {string | null} Base URL string (e.g., "file:///data/.../bundle-store/abc123") or null if not available
|
|
122
131
|
*/
|
|
123
132
|
export declare const getBaseURL: () => string | null;
|
|
133
|
+
/**
|
|
134
|
+
* Clears the runtime channel override and restores the original bundle.
|
|
135
|
+
*/
|
|
136
|
+
export declare const resetChannel: () => Promise<boolean>;
|
|
124
137
|
//# sourceMappingURL=native.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../src/native.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjE,OAAyB,EACvB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;AAMlD,eAAO,MAAM,mBAAmB;;CAE/B,CAAC;
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../src/native.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjE,OAAyB,EACvB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;AAMlD,eAAO,MAAM,mBAAmB;;CAE/B,CAAC;AA0DF,MAAM,MAAM,eAAe,GAAG;IAC5B,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAIF,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,eAAe,EACzD,WAAW,CAAC,EACZ,UAAU,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,eAO9C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG;IAC9C,MAAM,EAAE,YAAY,CAAC;IACrB,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAC1C,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC3E;;GAEG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,OAAO,CAAC,CAAC;AAuEpB;;GAEG;AACH,eAAO,MAAM,aAAa,QAAO,MAAM,GAAG,IAGzC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,MAAM,qBAElB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,QAAO,MAGjC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,QAAO,MAI9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,QAAO,MAE7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAO,MAEpC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAO,OAEpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,QAAO,MAAM,GAAG,IAG9C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,cAAc,QAAO,oBAYjC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QAAO,MAAM,EAWxC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAAO,OAEpC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,QAAO,MAAM,GAAG,IAMtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,QAAa,OAAO,CAAC,OAAO,CAUpD,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { TurboModule } from "react-native";
|
|
2
2
|
export interface UpdateBundleParams {
|
|
3
3
|
bundleId: string;
|
|
4
|
+
channel?: string;
|
|
4
5
|
fileUrl: string | null;
|
|
5
6
|
/**
|
|
6
7
|
* File hash for integrity/signature verification.
|
|
@@ -78,6 +79,12 @@ export interface Spec extends TurboModule {
|
|
|
78
79
|
* @returns true if clearing was successful
|
|
79
80
|
*/
|
|
80
81
|
clearCrashHistory(): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Clears the runtime channel override and restores the original bundle.
|
|
84
|
+
*
|
|
85
|
+
* @returns Promise that resolves to true if successful
|
|
86
|
+
*/
|
|
87
|
+
resetChannel(): Promise<boolean>;
|
|
81
88
|
/**
|
|
82
89
|
* Gets the base URL for the current active bundle directory.
|
|
83
90
|
* Returns the file:// URL to the bundle directory without trailing slash.
|
|
@@ -92,6 +99,7 @@ export interface Spec extends TurboModule {
|
|
|
92
99
|
MIN_BUNDLE_ID: string;
|
|
93
100
|
APP_VERSION: string | null;
|
|
94
101
|
CHANNEL: string;
|
|
102
|
+
DEFAULT_CHANNEL: string;
|
|
95
103
|
FINGERPRINT_HASH: string | null;
|
|
96
104
|
};
|
|
97
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeHotUpdater.d.ts","sourceRoot":"","sources":["../../../../src/specs/NativeHotUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,IAAK,SAAQ,WAAW;IAEvC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3D;;;;;;;;;;OAUG;IACH,cAAc,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG;QAC5C,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;QAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IAEF;;;;;OAKG;IACH,eAAe,IAAI,MAAM,EAAE,CAAC;IAE5B;;;;;OAKG;IACH,iBAAiB,IAAI,OAAO,CAAC;IAE7B;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,MAAM,CAAC;IAGzB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;CACH;;AAED,wBAAoE"}
|
|
1
|
+
{"version":3,"file":"NativeHotUpdater.d.ts","sourceRoot":"","sources":["../../../../src/specs/NativeHotUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,IAAK,SAAQ,WAAW;IAEvC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3D;;;;;;;;;;OAUG;IACH,cAAc,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG;QAC5C,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;QAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IAEF;;;;;OAKG;IACH,eAAe,IAAI,MAAM,EAAE,CAAC;IAE5B;;;;;OAKG;IACH,iBAAiB,IAAI,OAAO,CAAC;IAE7B;;;;OAIG;IACH,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjC;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,MAAM,CAAC;IAGzB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;CACH;;AAED,wBAAoE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "React Native OTA solution for self-hosted",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -120,14 +120,14 @@
|
|
|
120
120
|
"react-native": "0.79.1",
|
|
121
121
|
"react-native-builder-bob": "^0.40.10",
|
|
122
122
|
"typescript": "^5.8.3",
|
|
123
|
-
"hot-updater": "0.
|
|
123
|
+
"hot-updater": "0.26.0"
|
|
124
124
|
},
|
|
125
125
|
"dependencies": {
|
|
126
126
|
"use-sync-external-store": "1.5.0",
|
|
127
|
-
"@hot-updater/cli-tools": "0.
|
|
128
|
-
"@hot-updater/js": "0.
|
|
129
|
-
"@hot-updater/
|
|
130
|
-
"@hot-updater/core": "0.
|
|
127
|
+
"@hot-updater/cli-tools": "0.26.0",
|
|
128
|
+
"@hot-updater/js": "0.26.0",
|
|
129
|
+
"@hot-updater/core": "0.26.0",
|
|
130
|
+
"@hot-updater/plugin-core": "0.26.0"
|
|
131
131
|
},
|
|
132
132
|
"scripts": {
|
|
133
133
|
"build": "bob build && tsc -p plugin/tsconfig.build.json",
|
package/src/checkForUpdate.ts
CHANGED
|
@@ -5,12 +5,17 @@ import {
|
|
|
5
5
|
getAppVersion,
|
|
6
6
|
getBundleId,
|
|
7
7
|
getChannel,
|
|
8
|
+
getDefaultChannel,
|
|
8
9
|
getFingerprintHash,
|
|
9
10
|
getMinBundleId,
|
|
11
|
+
isChannelSwitched,
|
|
12
|
+
resetChannel,
|
|
10
13
|
updateBundle,
|
|
11
14
|
} from "./native";
|
|
12
15
|
import type { HotUpdaterResolver } from "./types";
|
|
13
16
|
|
|
17
|
+
const NIL_UUID = "00000000-0000-0000-0000-000000000000";
|
|
18
|
+
|
|
14
19
|
export interface CheckForUpdateOptions {
|
|
15
20
|
/**
|
|
16
21
|
* Update strategy
|
|
@@ -20,6 +25,12 @@ export interface CheckForUpdateOptions {
|
|
|
20
25
|
*/
|
|
21
26
|
updateStrategy: "appVersion" | "fingerprint";
|
|
22
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Override the current channel when checking for updates.
|
|
30
|
+
* The channel switch is only persisted after the returned update is applied.
|
|
31
|
+
*/
|
|
32
|
+
channel?: string;
|
|
33
|
+
|
|
23
34
|
requestHeaders?: Record<string, string>;
|
|
24
35
|
onError?: (error: Error) => void;
|
|
25
36
|
/**
|
|
@@ -42,6 +53,14 @@ export interface InternalCheckForUpdateOptions extends CheckForUpdateOptions {
|
|
|
42
53
|
resolver: HotUpdaterResolver;
|
|
43
54
|
}
|
|
44
55
|
|
|
56
|
+
const isResetToBuiltInResponse = (updateInfo: AppUpdateInfo): boolean => {
|
|
57
|
+
return (
|
|
58
|
+
updateInfo.status === "ROLLBACK" &&
|
|
59
|
+
updateInfo.id === NIL_UUID &&
|
|
60
|
+
updateInfo.fileUrl === null
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
45
64
|
export async function checkForUpdate(
|
|
46
65
|
options: InternalCheckForUpdateOptions,
|
|
47
66
|
): Promise<CheckForUpdateResult | null> {
|
|
@@ -60,13 +79,32 @@ export async function checkForUpdate(
|
|
|
60
79
|
const platform = Platform.OS as "ios" | "android";
|
|
61
80
|
const currentBundleId = getBundleId();
|
|
62
81
|
const minBundleId = getMinBundleId();
|
|
63
|
-
const
|
|
82
|
+
const defaultChannel = getDefaultChannel();
|
|
83
|
+
const isSwitched = isChannelSwitched();
|
|
84
|
+
const currentChannel = isSwitched ? getChannel() : defaultChannel;
|
|
85
|
+
const explicitChannel = options.channel || undefined;
|
|
86
|
+
const targetChannel = explicitChannel || currentChannel;
|
|
87
|
+
const isFirstRuntimeChannelSwitchAttempt =
|
|
88
|
+
!isSwitched &&
|
|
89
|
+
explicitChannel !== undefined &&
|
|
90
|
+
explicitChannel !== defaultChannel;
|
|
91
|
+
const requestBundleId = isFirstRuntimeChannelSwitchAttempt
|
|
92
|
+
? minBundleId
|
|
93
|
+
: currentBundleId;
|
|
64
94
|
|
|
65
95
|
if (!currentAppVersion) {
|
|
66
96
|
options.onError?.(new HotUpdaterError("Failed to get app version"));
|
|
67
97
|
return null;
|
|
68
98
|
}
|
|
69
99
|
|
|
100
|
+
if (isSwitched && explicitChannel && explicitChannel !== currentChannel) {
|
|
101
|
+
const error = new HotUpdaterError(
|
|
102
|
+
`Runtime channel is already switched to "${currentChannel}". Call HotUpdater.resetChannel() before checking "${explicitChannel}".`,
|
|
103
|
+
);
|
|
104
|
+
options.onError?.(error);
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
|
|
70
108
|
const fingerprintHash = getFingerprintHash();
|
|
71
109
|
|
|
72
110
|
if (!options.resolver?.checkUpdate) {
|
|
@@ -82,9 +120,9 @@ export async function checkForUpdate(
|
|
|
82
120
|
updateInfo = await options.resolver.checkUpdate({
|
|
83
121
|
platform,
|
|
84
122
|
appVersion: currentAppVersion,
|
|
85
|
-
bundleId:
|
|
123
|
+
bundleId: requestBundleId,
|
|
86
124
|
minBundleId,
|
|
87
|
-
channel,
|
|
125
|
+
channel: targetChannel,
|
|
88
126
|
updateStrategy: options.updateStrategy,
|
|
89
127
|
fingerprintHash,
|
|
90
128
|
requestHeaders: options.requestHeaders,
|
|
@@ -99,14 +137,36 @@ export async function checkForUpdate(
|
|
|
99
137
|
return null;
|
|
100
138
|
}
|
|
101
139
|
|
|
140
|
+
if (
|
|
141
|
+
explicitChannel &&
|
|
142
|
+
explicitChannel !== defaultChannel &&
|
|
143
|
+
!isSwitched &&
|
|
144
|
+
updateInfo.status === "ROLLBACK"
|
|
145
|
+
) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
|
|
102
149
|
return {
|
|
103
150
|
...updateInfo,
|
|
104
151
|
updateBundle: async () => {
|
|
152
|
+
if (
|
|
153
|
+
explicitChannel &&
|
|
154
|
+
isSwitched &&
|
|
155
|
+
isResetToBuiltInResponse(updateInfo)
|
|
156
|
+
) {
|
|
157
|
+
return resetChannel();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const runtimeChannel =
|
|
161
|
+
updateInfo.fileUrl !== null ? targetChannel : undefined;
|
|
162
|
+
|
|
105
163
|
return updateBundle({
|
|
106
164
|
bundleId: updateInfo.id,
|
|
165
|
+
channel: runtimeChannel,
|
|
107
166
|
fileUrl: updateInfo.fileUrl,
|
|
108
167
|
fileHash: updateInfo.fileHash,
|
|
109
168
|
status: updateInfo.status,
|
|
169
|
+
shouldSkipCurrentBundleIdCheck: isFirstRuntimeChannelSwitchAttempt,
|
|
110
170
|
});
|
|
111
171
|
},
|
|
112
172
|
};
|
package/src/index.ts
CHANGED
|
@@ -12,9 +12,12 @@ import {
|
|
|
12
12
|
getBundleId,
|
|
13
13
|
getChannel,
|
|
14
14
|
getCrashHistory,
|
|
15
|
+
getDefaultChannel,
|
|
15
16
|
getFingerprintHash,
|
|
16
17
|
getMinBundleId,
|
|
18
|
+
isChannelSwitched,
|
|
17
19
|
reload,
|
|
20
|
+
resetChannel,
|
|
18
21
|
type UpdateParams,
|
|
19
22
|
updateBundle,
|
|
20
23
|
} from "./native";
|
|
@@ -213,6 +216,27 @@ function createHotUpdaterClient() {
|
|
|
213
216
|
*/
|
|
214
217
|
getChannel,
|
|
215
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Fetches the build-time default channel of the app.
|
|
221
|
+
*
|
|
222
|
+
* This value does not change when a runtime channel override is active.
|
|
223
|
+
*
|
|
224
|
+
* @returns {string} The default release channel embedded in the app
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* const defaultChannel = HotUpdater.getDefaultChannel();
|
|
228
|
+
* console.log(`Default channel: ${defaultChannel}`);
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
getDefaultChannel,
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Returns whether the app is currently using a runtime channel override.
|
|
235
|
+
*
|
|
236
|
+
* @returns {boolean} true when a non-default channel has been applied
|
|
237
|
+
*/
|
|
238
|
+
isChannelSwitched,
|
|
239
|
+
|
|
216
240
|
/**
|
|
217
241
|
* Adds a listener to HotUpdater events.
|
|
218
242
|
*
|
|
@@ -237,6 +261,7 @@ function createHotUpdaterClient() {
|
|
|
237
261
|
*
|
|
238
262
|
* @param {Object} config - Update check configuration
|
|
239
263
|
* @param {string} config.source - Update server URL
|
|
264
|
+
* @param {string} [config.channel] - Optional channel override for this update check
|
|
240
265
|
* @param {Record<string, string>} [config.requestHeaders] - Request headers
|
|
241
266
|
*
|
|
242
267
|
* @returns {Promise<UpdateInfo | null>} Update information or null if up to date
|
|
@@ -315,6 +340,22 @@ function createHotUpdaterClient() {
|
|
|
315
340
|
return updateBundle(params);
|
|
316
341
|
},
|
|
317
342
|
|
|
343
|
+
/**
|
|
344
|
+
* Clears the runtime channel override and restores the original bundle.
|
|
345
|
+
*
|
|
346
|
+
* @returns {Promise<boolean>} Resolves with true if reset was successful
|
|
347
|
+
*/
|
|
348
|
+
resetChannel: async () => {
|
|
349
|
+
const ok = await resetChannel();
|
|
350
|
+
if (ok) {
|
|
351
|
+
hotUpdaterStore.setState({
|
|
352
|
+
isUpdateDownloaded: false,
|
|
353
|
+
progress: 0,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
return ok;
|
|
357
|
+
},
|
|
358
|
+
|
|
318
359
|
/**
|
|
319
360
|
* Fetches the fingerprint of the app.
|
|
320
361
|
*
|