@hot-updater/react-native 1.0.0-rc.1 → 1.0.0-rc.15
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/proguard-rules.pro +17 -2
- package/android/src/main/java/com/hotupdater/BuiltInAssetResolver.kt +286 -0
- package/android/src/main/java/com/hotupdater/BundleFileStorageService.kt +651 -637
- package/android/src/main/java/com/hotupdater/BundleMetadata.kt +10 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterException.kt +0 -13
- package/android/src/main/java/com/hotupdater/HotUpdaterImpl.kt +10 -14
- package/android/src/main/java/com/hotupdater/HotUpdaterRecoveryManager.kt +37 -54
- package/android/src/main/java/com/hotupdater/HotUpdaterRecoveryState.kt +64 -0
- package/android/src/main/java/com/hotupdater/OkHttpDownloadService.kt +19 -0
- package/android/src/main/java/com/hotupdater/TarArchiveInputStream.kt +214 -375
- package/android/src/main/java/com/hotupdater/TarBrArchiveExtractor.kt +119 -0
- package/android/src/newarch/HotUpdater.kt +7 -9
- package/android/src/newarch/HotUpdaterModule.kt +40 -20
- package/android/src/oldarch/HotUpdater.kt +7 -9
- package/android/src/oldarch/HotUpdaterModule.kt +40 -20
- package/android/src/test/java/com/hotupdater/BundleFileStorageServiceTest.kt +1126 -74
- package/android/src/test/java/com/hotupdater/HotUpdaterImplTest.kt +4 -5
- package/android/src/test/java/com/hotupdater/HotUpdaterRecoveryStateTest.kt +97 -0
- package/android/src/test/java/com/hotupdater/PendingCrashRecoveryTest.kt +44 -0
- package/android/src/test/java/com/hotupdater/TarBrArchiveExtractorTest.kt +206 -0
- package/ios/HotUpdater/Internal/BrotliFileDecompressor.swift +167 -0
- package/ios/HotUpdater/Internal/BuiltInAssetResolver.swift +196 -0
- package/ios/HotUpdater/Internal/BundleFileStorageService.swift +773 -1016
- package/ios/HotUpdater/Internal/BundleMetadata.swift +5 -0
- package/ios/HotUpdater/Internal/FileUtilities.swift +64 -0
- package/ios/HotUpdater/Internal/HotUpdater-Bridging-Header.h +0 -1
- package/ios/HotUpdater/Internal/HotUpdater.mm +5 -27
- package/ios/HotUpdater/Internal/HotUpdaterImpl.swift +149 -51
- package/ios/HotUpdater/Internal/NotificationExtension.swift +0 -2
- package/ios/HotUpdater/Internal/TarArchiveExtractor.swift +182 -311
- package/ios/HotUpdater/Internal/URLSessionDownloadService.swift +13 -72
- package/ios/HotUpdater/Recovery/HotUpdaterRecovery.h +16 -0
- package/ios/HotUpdater/Recovery/HotUpdaterRecovery.mm +83 -0
- package/ios/HotUpdater/Recovery/HotUpdaterRecoveryHooks.mm +49 -0
- package/lib/commonjs/checkForUpdate.js +32 -23
- package/lib/commonjs/checkForUpdate.js.map +1 -1
- package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js +97 -28
- package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js.map +1 -1
- package/lib/commonjs/error.js +4 -13
- package/lib/commonjs/error.js.map +1 -1
- package/lib/commonjs/fetchJSON.js +9 -2
- package/lib/commonjs/fetchJSON.js.map +1 -1
- package/lib/commonjs/httpClient.js +46 -29
- package/lib/commonjs/httpClient.js.map +1 -1
- package/lib/commonjs/httpClient.spec.js +57 -5
- package/lib/commonjs/httpClient.spec.js.map +1 -1
- package/lib/commonjs/index.js +31 -14
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.spec.js +56 -11
- package/lib/commonjs/index.spec.js.map +1 -1
- package/lib/commonjs/native.js +15 -14
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/native.spec.js +128 -22
- package/lib/commonjs/native.spec.js.map +1 -1
- package/lib/commonjs/{notifyAppReadyAnalytics.boundary.spec.js → notifyAppReadyInsights.boundary.spec.js} +28 -21
- package/lib/commonjs/notifyAppReadyInsights.boundary.spec.js.map +1 -0
- package/lib/commonjs/notifyAppReadyInsights.js +188 -0
- package/lib/commonjs/notifyAppReadyInsights.js.map +1 -0
- package/lib/commonjs/{notifyAppReadyAnalytics.spec.js → notifyAppReadyInsights.spec.js} +161 -29
- package/lib/commonjs/notifyAppReadyInsights.spec.js.map +1 -0
- package/lib/commonjs/{notifyAppReadyAnalytics.test-utils.js → notifyAppReadyInsights.test-utils.js} +3 -3
- package/lib/commonjs/notifyAppReadyInsights.test-utils.js.map +1 -0
- package/lib/commonjs/{notifyAppReadyAnalytics.transport.spec.js → notifyAppReadyInsights.transport.spec.js} +14 -7
- package/lib/commonjs/notifyAppReadyInsights.transport.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/store.js +3 -10
- package/lib/commonjs/store.js.map +1 -1
- package/lib/commonjs/store.notification.spec.js +12 -4
- package/lib/commonjs/store.notification.spec.js.map +1 -1
- package/lib/commonjs/store.spec.js +2 -136
- package/lib/commonjs/store.spec.js.map +1 -1
- package/lib/commonjs/wrap.js +11 -12
- package/lib/commonjs/wrap.js.map +1 -1
- package/lib/commonjs/wrap.spec.js +97 -25
- package/lib/commonjs/wrap.spec.js.map +1 -1
- package/lib/module/checkForUpdate.js +32 -23
- package/lib/module/checkForUpdate.js.map +1 -1
- package/lib/module/checkForUpdate.releaseCatalog.spec.js +97 -28
- package/lib/module/checkForUpdate.releaseCatalog.spec.js.map +1 -1
- package/lib/module/error.js +4 -13
- package/lib/module/error.js.map +1 -1
- package/lib/module/fetchJSON.js +7 -1
- package/lib/module/fetchJSON.js.map +1 -1
- package/lib/module/httpClient.js +48 -31
- package/lib/module/httpClient.js.map +1 -1
- package/lib/module/httpClient.spec.js +57 -5
- package/lib/module/httpClient.spec.js.map +1 -1
- package/lib/module/index.js +32 -15
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.spec.js +56 -11
- package/lib/module/index.spec.js.map +1 -1
- package/lib/module/native.js +13 -12
- package/lib/module/native.js.map +1 -1
- package/lib/module/native.spec.js +128 -22
- package/lib/module/native.spec.js.map +1 -1
- package/lib/module/{notifyAppReadyAnalytics.boundary.spec.js → notifyAppReadyInsights.boundary.spec.js} +23 -16
- package/lib/module/notifyAppReadyInsights.boundary.spec.js.map +1 -0
- package/lib/module/notifyAppReadyInsights.js +181 -0
- package/lib/module/notifyAppReadyInsights.js.map +1 -0
- package/lib/module/{notifyAppReadyAnalytics.spec.js → notifyAppReadyInsights.spec.js} +153 -21
- package/lib/module/notifyAppReadyInsights.spec.js.map +1 -0
- package/lib/module/{notifyAppReadyAnalytics.test-utils.js → notifyAppReadyInsights.test-utils.js} +3 -3
- package/lib/module/notifyAppReadyInsights.test-utils.js.map +1 -0
- package/lib/module/{notifyAppReadyAnalytics.transport.spec.js → notifyAppReadyInsights.transport.spec.js} +11 -4
- package/lib/module/notifyAppReadyInsights.transport.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/store.js +3 -10
- package/lib/module/store.js.map +1 -1
- package/lib/module/store.notification.spec.js +12 -4
- package/lib/module/store.notification.spec.js.map +1 -1
- package/lib/module/store.spec.js +2 -136
- package/lib/module/store.spec.js.map +1 -1
- package/lib/module/wrap.js +11 -12
- package/lib/module/wrap.js.map +1 -1
- package/lib/module/wrap.spec.js +99 -25
- package/lib/module/wrap.spec.js.map +1 -1
- package/lib/typescript/commonjs/checkForUpdate.d.ts +2 -3
- package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/commonjs/error.d.ts +4 -13
- package/lib/typescript/commonjs/error.d.ts.map +1 -1
- package/lib/typescript/commonjs/fetchJSON.d.ts +4 -0
- package/lib/typescript/commonjs/fetchJSON.d.ts.map +1 -1
- package/lib/typescript/commonjs/httpClient.d.ts +6 -6
- package/lib/typescript/commonjs/httpClient.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +4 -7
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/native.d.ts +5 -9
- package/lib/typescript/commonjs/native.d.ts.map +1 -1
- package/lib/typescript/commonjs/notifyAppReadyInsights.d.ts +25 -0
- package/lib/typescript/commonjs/notifyAppReadyInsights.d.ts.map +1 -0
- package/lib/typescript/commonjs/notifyAppReadyInsights.test-utils.d.ts +8 -0
- package/lib/typescript/commonjs/notifyAppReadyInsights.test-utils.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 +8 -35
- package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts.map +1 -1
- package/lib/typescript/commonjs/store.d.ts +1 -3
- package/lib/typescript/commonjs/store.d.ts.map +1 -1
- package/lib/typescript/commonjs/wrap.types.d.ts +5 -8
- package/lib/typescript/commonjs/wrap.types.d.ts.map +1 -1
- package/lib/typescript/module/checkForUpdate.d.ts +2 -3
- package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/module/error.d.ts +4 -13
- package/lib/typescript/module/error.d.ts.map +1 -1
- package/lib/typescript/module/fetchJSON.d.ts +4 -0
- package/lib/typescript/module/fetchJSON.d.ts.map +1 -1
- package/lib/typescript/module/httpClient.d.ts +6 -6
- package/lib/typescript/module/httpClient.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +4 -7
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/native.d.ts +5 -9
- package/lib/typescript/module/native.d.ts.map +1 -1
- package/lib/typescript/module/notifyAppReadyInsights.d.ts +25 -0
- package/lib/typescript/module/notifyAppReadyInsights.d.ts.map +1 -0
- package/lib/typescript/module/notifyAppReadyInsights.test-utils.d.ts +8 -0
- package/lib/typescript/module/notifyAppReadyInsights.test-utils.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 +8 -35
- package/lib/typescript/module/specs/NativeHotUpdater.d.ts.map +1 -1
- package/lib/typescript/module/store.d.ts +1 -3
- package/lib/typescript/module/store.d.ts.map +1 -1
- package/lib/typescript/module/wrap.types.d.ts +5 -8
- package/lib/typescript/module/wrap.types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/checkForUpdate.releaseCatalog.spec.ts +137 -61
- package/src/checkForUpdate.ts +35 -29
- package/src/error.ts +4 -14
- package/src/fetchJSON.ts +12 -1
- package/src/httpClient.spec.ts +70 -5
- package/src/httpClient.ts +78 -64
- package/src/index.spec.ts +59 -11
- package/src/index.ts +41 -17
- package/src/native.spec.ts +133 -22
- package/src/native.ts +21 -32
- package/src/{notifyAppReadyAnalytics.boundary.spec.ts → notifyAppReadyInsights.boundary.spec.ts} +25 -17
- package/src/{notifyAppReadyAnalytics.spec.ts → notifyAppReadyInsights.spec.ts} +141 -22
- package/src/{notifyAppReadyAnalytics.test-utils.ts → notifyAppReadyInsights.test-utils.ts} +4 -4
- package/src/{notifyAppReadyAnalytics.transport.spec.ts → notifyAppReadyInsights.transport.spec.ts} +13 -5
- package/src/notifyAppReadyInsights.ts +293 -0
- package/src/sdkVersion.ts +1 -1
- package/src/specs/NativeHotUpdater.ts +8 -36
- package/src/store.notification.spec.ts +13 -3
- package/src/store.spec.ts +0 -157
- package/src/store.ts +2 -23
- package/src/wrap.spec.ts +109 -31
- package/src/wrap.tsx +11 -11
- package/src/wrap.types.ts +5 -8
- package/android/src/main/java/com/hotupdater/DecompressService.kt +0 -89
- package/android/src/main/java/com/hotupdater/DecompressionStrategy.kt +0 -26
- package/android/src/main/java/com/hotupdater/TarBrDecompressionStrategy.kt +0 -117
- package/android/src/main/java/com/hotupdater/TarGzDecompressionStrategy.kt +0 -117
- package/android/src/main/java/com/hotupdater/ZipDecompressionStrategy.kt +0 -192
- package/android/src/test/java/com/hotupdater/TarArchiveInputStreamTest.kt +0 -68
- package/ios/HotUpdater/Internal/ArchiveExtractionUtilities.swift +0 -178
- package/ios/HotUpdater/Internal/DecompressService.swift +0 -112
- package/ios/HotUpdater/Internal/DecompressionStrategy.swift +0 -22
- package/ios/HotUpdater/Internal/StreamingTarArchiveExtractor.swift +0 -370
- package/ios/HotUpdater/Internal/TarBrDecompressionStrategy.swift +0 -39
- package/ios/HotUpdater/Internal/TarGzDecompressionStrategy.swift +0 -59
- package/ios/HotUpdater/Internal/ZipArchiveExtractor.swift +0 -482
- package/ios/HotUpdater/Internal/ZipDecompressionStrategy.swift +0 -56
- package/lib/commonjs/notifyAppReadyAnalytics.boundary.spec.js.map +0 -1
- package/lib/commonjs/notifyAppReadyAnalytics.js +0 -133
- package/lib/commonjs/notifyAppReadyAnalytics.js.map +0 -1
- package/lib/commonjs/notifyAppReadyAnalytics.spec.js.map +0 -1
- package/lib/commonjs/notifyAppReadyAnalytics.test-utils.js.map +0 -1
- package/lib/commonjs/notifyAppReadyAnalytics.transport.spec.js.map +0 -1
- package/lib/module/notifyAppReadyAnalytics.boundary.spec.js.map +0 -1
- package/lib/module/notifyAppReadyAnalytics.js +0 -128
- package/lib/module/notifyAppReadyAnalytics.js.map +0 -1
- package/lib/module/notifyAppReadyAnalytics.spec.js.map +0 -1
- package/lib/module/notifyAppReadyAnalytics.test-utils.js.map +0 -1
- package/lib/module/notifyAppReadyAnalytics.transport.spec.js.map +0 -1
- package/lib/typescript/commonjs/notifyAppReadyAnalytics.d.ts +0 -13
- package/lib/typescript/commonjs/notifyAppReadyAnalytics.d.ts.map +0 -1
- package/lib/typescript/commonjs/notifyAppReadyAnalytics.test-utils.d.ts +0 -8
- package/lib/typescript/commonjs/notifyAppReadyAnalytics.test-utils.d.ts.map +0 -1
- package/lib/typescript/module/notifyAppReadyAnalytics.d.ts +0 -13
- package/lib/typescript/module/notifyAppReadyAnalytics.d.ts.map +0 -1
- package/lib/typescript/module/notifyAppReadyAnalytics.test-utils.d.ts +0 -8
- package/lib/typescript/module/notifyAppReadyAnalytics.test-utils.d.ts.map +0 -1
- package/src/notifyAppReadyAnalytics.ts +0 -194
package/src/httpClient.spec.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ArtifactInfo, ReleaseCatalog } from "@hot-updater/core";
|
|
2
2
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
3
|
|
|
4
|
+
import { FetchJSONResponseError } from "./fetchJSON";
|
|
4
5
|
import { createHttpClient } from "./httpClient";
|
|
5
6
|
|
|
6
7
|
const mocks = vi.hoisted(() => {
|
|
@@ -18,12 +19,28 @@ vi.mock("./releaseCatalogCache", () => ({
|
|
|
18
19
|
}));
|
|
19
20
|
|
|
20
21
|
vi.mock("./fetchJSON", () => ({
|
|
22
|
+
FetchJSONResponseError: class FetchJSONResponseError extends Error {
|
|
23
|
+
constructor(
|
|
24
|
+
readonly status: number,
|
|
25
|
+
statusText: string,
|
|
26
|
+
) {
|
|
27
|
+
super(statusText);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
21
30
|
fetchJSON: mocks.fetchJSON,
|
|
22
31
|
}));
|
|
23
32
|
|
|
24
33
|
const artifact: ArtifactInfo = {
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
artifactProtocolVersion: 1,
|
|
35
|
+
assets: {
|
|
36
|
+
"index.ios.bundle": {
|
|
37
|
+
file: { url: "/storage/index.bundle.br" },
|
|
38
|
+
fileHash: "bundle-hash",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
manifestFileHash: "manifest-hash",
|
|
42
|
+
manifestUrl: "/storage/manifest.json",
|
|
43
|
+
archiveUrl: "/storage/bundle.tar.br",
|
|
27
44
|
};
|
|
28
45
|
|
|
29
46
|
const catalog: ReleaseCatalog = {
|
|
@@ -93,14 +110,24 @@ describe("private HotUpdater HTTP client", () => {
|
|
|
93
110
|
}),
|
|
94
111
|
).resolves.toEqual({
|
|
95
112
|
...artifact,
|
|
96
|
-
|
|
113
|
+
assets: {
|
|
114
|
+
"index.ios.bundle": {
|
|
115
|
+
file: {
|
|
116
|
+
url: "https://first.example.com/hot-updater/storage/index.bundle.br",
|
|
117
|
+
},
|
|
118
|
+
fileHash: "bundle-hash",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
manifestUrl:
|
|
122
|
+
"https://first.example.com/hot-updater/storage/manifest.json",
|
|
123
|
+
archiveUrl: "https://first.example.com/hot-updater/storage/bundle.tar.br",
|
|
97
124
|
});
|
|
98
125
|
|
|
99
126
|
expect(resolveBaseURL).toHaveBeenCalledOnce();
|
|
100
127
|
expect(mocks.fetchJSON).toHaveBeenCalledWith({
|
|
101
128
|
requestHeaders: undefined,
|
|
102
129
|
requestTimeout: undefined,
|
|
103
|
-
url: "https://first.example.com/hot-updater/artifacts/target/from/current",
|
|
130
|
+
url: "https://first.example.com/hot-updater/artifacts/v1/target/from/current",
|
|
104
131
|
});
|
|
105
132
|
|
|
106
133
|
await client.createSession();
|
|
@@ -110,7 +137,12 @@ describe("private HotUpdater HTTP client", () => {
|
|
|
110
137
|
it("rejects non-storage relative artifact URLs", async () => {
|
|
111
138
|
mocks.fetchJSON.mockResolvedValue({
|
|
112
139
|
...artifact,
|
|
113
|
-
|
|
140
|
+
assets: {
|
|
141
|
+
"index.ios.bundle": {
|
|
142
|
+
file: { url: "/private/index.bundle.br" },
|
|
143
|
+
fileHash: "bundle-hash",
|
|
144
|
+
},
|
|
145
|
+
},
|
|
114
146
|
});
|
|
115
147
|
const session = await createHttpClient(
|
|
116
148
|
"https://updates.example.com",
|
|
@@ -124,6 +156,39 @@ describe("private HotUpdater HTTP client", () => {
|
|
|
124
156
|
).rejects.toThrow("client-relative storage paths");
|
|
125
157
|
});
|
|
126
158
|
|
|
159
|
+
it("rejects a legacy artifact response", async () => {
|
|
160
|
+
mocks.fetchJSON.mockResolvedValue({
|
|
161
|
+
fileHash: "archive-hash",
|
|
162
|
+
fileUrl: "/storage/bundle.zip",
|
|
163
|
+
});
|
|
164
|
+
const session = await createHttpClient(
|
|
165
|
+
"https://updates.example.com",
|
|
166
|
+
).createSession();
|
|
167
|
+
|
|
168
|
+
await expect(
|
|
169
|
+
session.resolveArtifact({
|
|
170
|
+
currentBundleId: "current",
|
|
171
|
+
targetBundleId: "target",
|
|
172
|
+
}),
|
|
173
|
+
).rejects.toThrow("does not support artifact protocol 1");
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("reports an old server without the v1 endpoint explicitly", async () => {
|
|
177
|
+
mocks.fetchJSON.mockRejectedValue(
|
|
178
|
+
new FetchJSONResponseError(404, "Not Found"),
|
|
179
|
+
);
|
|
180
|
+
const session = await createHttpClient(
|
|
181
|
+
"https://updates.example.com",
|
|
182
|
+
).createSession();
|
|
183
|
+
|
|
184
|
+
await expect(
|
|
185
|
+
session.resolveArtifact({
|
|
186
|
+
currentBundleId: "current",
|
|
187
|
+
targetBundleId: "target",
|
|
188
|
+
}),
|
|
189
|
+
).rejects.toThrow("does not support artifact protocol 1");
|
|
190
|
+
});
|
|
191
|
+
|
|
127
192
|
it("requires a functional baseURL to resolve to a non-empty string", async () => {
|
|
128
193
|
await expect(createHttpClient(() => "").createSession()).rejects.toThrow(
|
|
129
194
|
"baseURL function must return a non-empty string",
|
package/src/httpClient.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ARTIFACT_PROTOCOL_VERSION,
|
|
2
3
|
encodeChannelKey,
|
|
3
4
|
type ArtifactInfo,
|
|
4
5
|
type ReleaseCatalog,
|
|
5
6
|
} from "@hot-updater/core";
|
|
6
7
|
import { canonicalizeAppVersion } from "@hot-updater/plugin-core";
|
|
7
8
|
|
|
8
|
-
import { fetchJSON } from "./fetchJSON";
|
|
9
|
+
import { fetchJSON, FetchJSONResponseError } from "./fetchJSON";
|
|
9
10
|
import { fetchReleaseCatalogWithCache } from "./releaseCatalogCache";
|
|
10
11
|
import { HOT_UPDATER_SDK_VERSION } from "./sdkVersion";
|
|
11
12
|
import type { HotUpdaterBaseURL } from "./types";
|
|
@@ -27,7 +28,7 @@ export interface ArtifactRequest {
|
|
|
27
28
|
readonly requestTimeout?: number;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
interface
|
|
31
|
+
interface InsightsEventCommonParams {
|
|
31
32
|
readonly installId: string;
|
|
32
33
|
readonly userId?: string;
|
|
33
34
|
readonly username?: string;
|
|
@@ -42,30 +43,30 @@ interface AnalyticsEventCommonParams {
|
|
|
42
43
|
readonly requestTimeout?: number;
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
type
|
|
46
|
-
readonly type: "
|
|
46
|
+
type InsightsTransitionEventParams = InsightsEventCommonParams & {
|
|
47
|
+
readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED";
|
|
47
48
|
readonly fromBundleId: string;
|
|
48
49
|
readonly toBundleId: string;
|
|
49
50
|
readonly updateStrategy: "fingerprint" | "appVersion";
|
|
50
51
|
};
|
|
51
52
|
|
|
52
|
-
type
|
|
53
|
+
type InsightsUnchangedEventParams = InsightsEventCommonParams & {
|
|
53
54
|
readonly type: "UNCHANGED";
|
|
54
55
|
readonly fromBundleId: null;
|
|
55
56
|
readonly toBundleId: string;
|
|
56
57
|
readonly updateStrategy: null;
|
|
57
58
|
};
|
|
58
59
|
|
|
59
|
-
export type
|
|
60
|
-
|
|
|
61
|
-
|
|
|
60
|
+
export type InsightsEventParams =
|
|
61
|
+
| InsightsTransitionEventParams
|
|
62
|
+
| InsightsUnchangedEventParams;
|
|
62
63
|
|
|
63
64
|
export interface HotUpdaterHttpSession {
|
|
64
65
|
fetchReleaseCatalog: (
|
|
65
66
|
params: ReleaseCatalogRequest,
|
|
66
67
|
) => Promise<ReleaseCatalog>;
|
|
67
68
|
resolveArtifact: (params: ArtifactRequest) => Promise<ArtifactInfo>;
|
|
68
|
-
|
|
69
|
+
sendInsightsEvent: (params: InsightsEventParams) => Promise<void>;
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
export interface HotUpdaterHttpClient {
|
|
@@ -101,55 +102,57 @@ const resolveArtifactUrls = (
|
|
|
101
102
|
info: ArtifactInfo,
|
|
102
103
|
): ArtifactInfo => ({
|
|
103
104
|
...info,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
...asset.file,
|
|
129
|
-
url: resolveArtifactUrl(baseURL, asset.file.url),
|
|
130
|
-
},
|
|
131
|
-
}
|
|
132
|
-
: {}),
|
|
133
|
-
...(asset.patch
|
|
134
|
-
? {
|
|
135
|
-
patch: {
|
|
136
|
-
...asset.patch,
|
|
137
|
-
patchUrl: resolveArtifactUrl(
|
|
138
|
-
baseURL,
|
|
139
|
-
asset.patch.patchUrl,
|
|
140
|
-
),
|
|
141
|
-
},
|
|
142
|
-
}
|
|
143
|
-
: {}),
|
|
144
|
-
},
|
|
145
|
-
]),
|
|
146
|
-
),
|
|
147
|
-
}),
|
|
105
|
+
manifestUrl: resolveArtifactUrl(baseURL, info.manifestUrl),
|
|
106
|
+
...(info.archiveUrl
|
|
107
|
+
? { archiveUrl: resolveArtifactUrl(baseURL, info.archiveUrl) }
|
|
108
|
+
: {}),
|
|
109
|
+
assets: Object.fromEntries(
|
|
110
|
+
Object.entries(info.assets).map(([path, asset]) => [
|
|
111
|
+
path,
|
|
112
|
+
{
|
|
113
|
+
...asset,
|
|
114
|
+
file: {
|
|
115
|
+
...asset.file,
|
|
116
|
+
url: resolveArtifactUrl(baseURL, asset.file.url),
|
|
117
|
+
},
|
|
118
|
+
...(asset.patch
|
|
119
|
+
? {
|
|
120
|
+
patch: {
|
|
121
|
+
...asset.patch,
|
|
122
|
+
patchUrl: resolveArtifactUrl(baseURL, asset.patch.patchUrl),
|
|
123
|
+
},
|
|
124
|
+
}
|
|
125
|
+
: {}),
|
|
126
|
+
},
|
|
127
|
+
]),
|
|
128
|
+
),
|
|
148
129
|
});
|
|
149
130
|
|
|
150
|
-
const
|
|
131
|
+
const requireArtifactProtocolV1 = (info: ArtifactInfo): ArtifactInfo => {
|
|
132
|
+
if (
|
|
133
|
+
info.artifactProtocolVersion !== ARTIFACT_PROTOCOL_VERSION ||
|
|
134
|
+
!info.assets ||
|
|
135
|
+
!info.manifestUrl ||
|
|
136
|
+
!info.manifestFileHash ||
|
|
137
|
+
(info.archiveUrl !== undefined && typeof info.archiveUrl !== "string")
|
|
138
|
+
) {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`Server does not support artifact protocol ${ARTIFACT_PROTOCOL_VERSION}.`,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
for (const asset of Object.values(info.assets)) {
|
|
144
|
+
if (!asset.file?.url || !asset.fileHash) {
|
|
145
|
+
throw new Error(
|
|
146
|
+
"Artifact protocol 1 requires an original file for every asset.",
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return info;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const sendInsightsEvent = async (
|
|
151
154
|
baseURL: string,
|
|
152
|
-
params:
|
|
155
|
+
params: InsightsEventParams,
|
|
153
156
|
): Promise<void> => {
|
|
154
157
|
const controller = new AbortController();
|
|
155
158
|
const timeoutId = setTimeout(() => {
|
|
@@ -241,16 +244,27 @@ const createSession = (baseURL: string): HotUpdaterHttpSession => ({
|
|
|
241
244
|
});
|
|
242
245
|
},
|
|
243
246
|
resolveArtifact: async (params): Promise<ArtifactInfo> => {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
params.
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
247
|
+
let info: ArtifactInfo;
|
|
248
|
+
try {
|
|
249
|
+
info = await fetchJSON<ArtifactInfo>({
|
|
250
|
+
requestHeaders: params.requestHeaders,
|
|
251
|
+
requestTimeout: params.requestTimeout,
|
|
252
|
+
url: `${baseURL}/artifacts/v1/${encodeURIComponent(
|
|
253
|
+
params.targetBundleId,
|
|
254
|
+
)}/from/${encodeURIComponent(params.currentBundleId)}`,
|
|
255
|
+
});
|
|
256
|
+
} catch (error) {
|
|
257
|
+
if (error instanceof FetchJSONResponseError && error.status === 404) {
|
|
258
|
+
throw new Error(
|
|
259
|
+
`Server does not support artifact protocol ${ARTIFACT_PROTOCOL_VERSION}.`,
|
|
260
|
+
{ cause: error },
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
throw error;
|
|
264
|
+
}
|
|
265
|
+
return resolveArtifactUrls(baseURL, requireArtifactProtocolV1(info));
|
|
252
266
|
},
|
|
253
|
-
|
|
267
|
+
sendInsightsEvent: (params) => sendInsightsEvent(baseURL, params),
|
|
254
268
|
});
|
|
255
269
|
|
|
256
270
|
/** Creates the private HTTP client used by HotUpdater.init and HotUpdater.wrap. */
|
package/src/index.spec.ts
CHANGED
|
@@ -22,7 +22,7 @@ const mocks = vi.hoisted(() => {
|
|
|
22
22
|
})),
|
|
23
23
|
getAppVersion: vi.fn(() => "1.0.0"),
|
|
24
24
|
getBaseURL: vi.fn(() => null),
|
|
25
|
-
|
|
25
|
+
getUpdateId: vi.fn(() => "release-id"),
|
|
26
26
|
getChannel: vi.fn(() => "production"),
|
|
27
27
|
getCohort: vi.fn(() => "123"),
|
|
28
28
|
getCrashHistory: vi.fn(() => []),
|
|
@@ -31,7 +31,6 @@ const mocks = vi.hoisted(() => {
|
|
|
31
31
|
getInstallId: vi.fn(() => "install-id"),
|
|
32
32
|
getManifest: vi.fn(() => null),
|
|
33
33
|
getMinBundleId: vi.fn(() => "min-bundle-id"),
|
|
34
|
-
getReleaseId: vi.fn(async () => null),
|
|
35
34
|
init: vi.fn(),
|
|
36
35
|
isChannelSwitched: vi.fn(() => false),
|
|
37
36
|
notifyAppReady: vi.fn(() => ({ status: "UNCHANGED" as const })),
|
|
@@ -45,6 +44,8 @@ const mocks = vi.hoisted(() => {
|
|
|
45
44
|
};
|
|
46
45
|
});
|
|
47
46
|
|
|
47
|
+
vi.mock("react-native", () => ({ Platform: { OS: "ios" } }));
|
|
48
|
+
|
|
48
49
|
vi.mock("./httpClient", () => ({
|
|
49
50
|
createHttpClient: mocks.createHttpClient,
|
|
50
51
|
}));
|
|
@@ -57,9 +58,11 @@ vi.mock("./native", () => ({
|
|
|
57
58
|
addListener: mocks.addListener,
|
|
58
59
|
clearCrashHistory: mocks.clearCrashHistory,
|
|
59
60
|
getPublicActiveUpdateState: mocks.getActiveUpdateState,
|
|
61
|
+
getActiveUpdateState: mocks.getActiveUpdateState,
|
|
62
|
+
getBundleId: () => "bundle-id",
|
|
60
63
|
getAppVersion: mocks.getAppVersion,
|
|
61
64
|
getBaseURL: mocks.getBaseURL,
|
|
62
|
-
|
|
65
|
+
getUpdateId: mocks.getUpdateId,
|
|
63
66
|
getChannel: mocks.getChannel,
|
|
64
67
|
getCohort: mocks.getCohort,
|
|
65
68
|
getCrashHistory: mocks.getCrashHistory,
|
|
@@ -68,7 +71,6 @@ vi.mock("./native", () => ({
|
|
|
68
71
|
getInstallId: mocks.getInstallId,
|
|
69
72
|
getManifest: mocks.getManifest,
|
|
70
73
|
getMinBundleId: mocks.getMinBundleId,
|
|
71
|
-
getReleaseId: mocks.getReleaseId,
|
|
72
74
|
isChannelSwitched: mocks.isChannelSwitched,
|
|
73
75
|
notifyAppReady: mocks.notifyAppReady,
|
|
74
76
|
reload: mocks.reload,
|
|
@@ -97,13 +99,21 @@ describe("HotUpdater client initialization", () => {
|
|
|
97
99
|
mocks.wrap.mockImplementation((Component: unknown) => Component);
|
|
98
100
|
});
|
|
99
101
|
|
|
102
|
+
it("exposes the console ID through the existing getter only", async () => {
|
|
103
|
+
const HotUpdater = await importHotUpdater();
|
|
104
|
+
|
|
105
|
+
expect(HotUpdater.getBundleId()).toBe("release-id");
|
|
106
|
+
expect(HotUpdater).not.toHaveProperty("getReleaseId");
|
|
107
|
+
expect(HotUpdater).not.toHaveProperty("getUpdateId");
|
|
108
|
+
});
|
|
109
|
+
|
|
100
110
|
it("initializes a private HTTP client from the required baseURL", async () => {
|
|
101
111
|
const client = { createSession: vi.fn() };
|
|
102
112
|
mocks.createHttpClient.mockReturnValue(client as never);
|
|
103
113
|
const HotUpdater = await importHotUpdater();
|
|
104
114
|
|
|
105
115
|
HotUpdater.init({
|
|
106
|
-
|
|
116
|
+
insights: true,
|
|
107
117
|
baseURL: "https://updates.example.com",
|
|
108
118
|
requestHeaders: { Authorization: "Bearer token" },
|
|
109
119
|
requestTimeout: 1000,
|
|
@@ -113,7 +123,7 @@ describe("HotUpdater client initialization", () => {
|
|
|
113
123
|
"https://updates.example.com",
|
|
114
124
|
);
|
|
115
125
|
expect(mocks.init).toHaveBeenCalledWith({
|
|
116
|
-
|
|
126
|
+
insights: true,
|
|
117
127
|
client,
|
|
118
128
|
requestHeaders: { Authorization: "Bearer token" },
|
|
119
129
|
requestTimeout: 1000,
|
|
@@ -130,6 +140,44 @@ describe("HotUpdater client initialization", () => {
|
|
|
130
140
|
expect(resolveBaseURL).not.toHaveBeenCalled();
|
|
131
141
|
});
|
|
132
142
|
|
|
143
|
+
it("enables insights by default for init and wrap", async () => {
|
|
144
|
+
const HotUpdater = await importHotUpdater();
|
|
145
|
+
|
|
146
|
+
HotUpdater.init({ baseURL: "https://updates.example.com" });
|
|
147
|
+
HotUpdater.wrap({
|
|
148
|
+
baseURL: "https://updates.example.com",
|
|
149
|
+
updateStrategy: "appVersion",
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
expect(mocks.init).toHaveBeenCalledWith(
|
|
153
|
+
expect.objectContaining({ insights: true }),
|
|
154
|
+
);
|
|
155
|
+
expect(mocks.wrap).toHaveBeenCalledWith(
|
|
156
|
+
expect.objectContaining({ insights: true }),
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("preserves an explicit insights opt-out", async () => {
|
|
161
|
+
const HotUpdater = await importHotUpdater();
|
|
162
|
+
|
|
163
|
+
HotUpdater.init({
|
|
164
|
+
baseURL: "https://updates.example.com",
|
|
165
|
+
insights: false,
|
|
166
|
+
});
|
|
167
|
+
HotUpdater.wrap({
|
|
168
|
+
baseURL: "https://updates.example.com",
|
|
169
|
+
insights: false,
|
|
170
|
+
updateStrategy: "appVersion",
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
expect(mocks.init).toHaveBeenCalledWith(
|
|
174
|
+
expect.objectContaining({ insights: false }),
|
|
175
|
+
);
|
|
176
|
+
expect(mocks.wrap).toHaveBeenCalledWith(
|
|
177
|
+
expect.objectContaining({ insights: false }),
|
|
178
|
+
);
|
|
179
|
+
});
|
|
180
|
+
|
|
133
181
|
it("requires baseURL and rejects the removed resolver shape", async () => {
|
|
134
182
|
const HotUpdater = await importHotUpdater();
|
|
135
183
|
|
|
@@ -171,13 +219,13 @@ describe("HotUpdater client initialization", () => {
|
|
|
171
219
|
expect(wrapOptions.updateStrategy).toBe("appVersion");
|
|
172
220
|
});
|
|
173
221
|
|
|
174
|
-
it("merges settings and carries the
|
|
222
|
+
it("merges settings and carries the insights gate to checks", async () => {
|
|
175
223
|
const client = { createSession: vi.fn() };
|
|
176
224
|
mocks.createHttpClient.mockReturnValue(client as never);
|
|
177
225
|
const checkOnError = vi.fn();
|
|
178
226
|
const HotUpdater = await importHotUpdater();
|
|
179
227
|
HotUpdater.init({
|
|
180
|
-
|
|
228
|
+
insights: true,
|
|
181
229
|
baseURL: "https://updates.example.com",
|
|
182
230
|
requestHeaders: { Authorization: "Bearer token" },
|
|
183
231
|
requestTimeout: 1000,
|
|
@@ -190,7 +238,7 @@ describe("HotUpdater client initialization", () => {
|
|
|
190
238
|
});
|
|
191
239
|
|
|
192
240
|
expect(mocks.checkForUpdate).toHaveBeenCalledWith({
|
|
193
|
-
|
|
241
|
+
insights: true,
|
|
194
242
|
client,
|
|
195
243
|
onError: checkOnError,
|
|
196
244
|
requestHeaders: {
|
|
@@ -208,13 +256,13 @@ describe("HotUpdater client initialization", () => {
|
|
|
208
256
|
const HotUpdater = await importHotUpdater();
|
|
209
257
|
|
|
210
258
|
HotUpdater.wrap({
|
|
211
|
-
|
|
259
|
+
insights: true,
|
|
212
260
|
baseURL: "https://updates.example.com",
|
|
213
261
|
updateStrategy: "appVersion",
|
|
214
262
|
});
|
|
215
263
|
|
|
216
264
|
expect(mocks.wrap).toHaveBeenCalledWith({
|
|
217
|
-
|
|
265
|
+
insights: true,
|
|
218
266
|
client,
|
|
219
267
|
updateStrategy: "appVersion",
|
|
220
268
|
});
|
package/src/index.ts
CHANGED
|
@@ -7,10 +7,12 @@ import { createHttpClient, type HotUpdaterHttpClient } from "./httpClient";
|
|
|
7
7
|
import {
|
|
8
8
|
addListener,
|
|
9
9
|
getPublicActiveUpdateState,
|
|
10
|
+
getActiveUpdateState,
|
|
11
|
+
getBundleId,
|
|
10
12
|
clearCrashHistory,
|
|
11
13
|
getAppVersion,
|
|
12
14
|
getBaseURL,
|
|
13
|
-
|
|
15
|
+
getUpdateId,
|
|
14
16
|
getChannel,
|
|
15
17
|
getCohort,
|
|
16
18
|
getCrashHistory,
|
|
@@ -19,7 +21,6 @@ import {
|
|
|
19
21
|
getInstallId,
|
|
20
22
|
getManifest,
|
|
21
23
|
getMinBundleId,
|
|
22
|
-
getReleaseId,
|
|
23
24
|
isChannelSwitched,
|
|
24
25
|
notifyAppReady,
|
|
25
26
|
reload,
|
|
@@ -30,6 +31,7 @@ import {
|
|
|
30
31
|
type UpdateParams,
|
|
31
32
|
updateBundle,
|
|
32
33
|
} from "./native";
|
|
34
|
+
import { reportBundleDownloaded } from "./notifyAppReadyInsights";
|
|
33
35
|
import { hotUpdaterStore } from "./store";
|
|
34
36
|
import {
|
|
35
37
|
type AutoUpdateOptions,
|
|
@@ -101,12 +103,13 @@ function createHotUpdaterClient() {
|
|
|
101
103
|
|
|
102
104
|
// Global configuration stored from wrap
|
|
103
105
|
const globalConfig: {
|
|
104
|
-
|
|
106
|
+
insights: boolean;
|
|
105
107
|
client: HotUpdaterHttpClient | null;
|
|
106
108
|
requestHeaders?: Record<string, string>;
|
|
107
109
|
requestTimeout?: number;
|
|
108
110
|
onError?: (error: unknown) => void;
|
|
109
111
|
} = {
|
|
112
|
+
insights: true,
|
|
110
113
|
client: null,
|
|
111
114
|
};
|
|
112
115
|
|
|
@@ -158,6 +161,7 @@ function createHotUpdaterClient() {
|
|
|
158
161
|
const { baseURL, ...rest } = autoOptions;
|
|
159
162
|
return {
|
|
160
163
|
...rest,
|
|
164
|
+
insights: rest.insights ?? true,
|
|
161
165
|
client: createHttpClient(baseURL),
|
|
162
166
|
};
|
|
163
167
|
}
|
|
@@ -177,6 +181,7 @@ function createHotUpdaterClient() {
|
|
|
177
181
|
const { baseURL, ...baseURLRest } = rest;
|
|
178
182
|
return {
|
|
179
183
|
...baseURLRest,
|
|
184
|
+
insights: baseURLRest.insights ?? true,
|
|
180
185
|
client: createHttpClient(baseURL),
|
|
181
186
|
};
|
|
182
187
|
}
|
|
@@ -188,7 +193,7 @@ function createHotUpdaterClient() {
|
|
|
188
193
|
normalizedOptions: InternalInitOptions | InternalWrapOptions,
|
|
189
194
|
options: HotUpdaterOptions | HotUpdaterInitOptions,
|
|
190
195
|
) => {
|
|
191
|
-
globalConfig.
|
|
196
|
+
globalConfig.insights = normalizedOptions.insights ?? true;
|
|
192
197
|
globalConfig.client = normalizedOptions.client;
|
|
193
198
|
globalConfig.requestHeaders = options.requestHeaders;
|
|
194
199
|
globalConfig.requestTimeout = options.requestTimeout;
|
|
@@ -333,16 +338,14 @@ function createHotUpdaterClient() {
|
|
|
333
338
|
getActiveUpdateState: async () => getPublicActiveUpdateState(),
|
|
334
339
|
|
|
335
340
|
/**
|
|
336
|
-
*
|
|
341
|
+
* Returns the selected update ID, matching the ID shown in the console.
|
|
342
|
+
* A staged update can change this ID before the app reloads.
|
|
337
343
|
*/
|
|
338
|
-
getBundleId,
|
|
344
|
+
getBundleId: getUpdateId,
|
|
339
345
|
|
|
340
346
|
/** Returns the minimum bundle ID based on the native app build time. */
|
|
341
347
|
getMinBundleId,
|
|
342
348
|
|
|
343
|
-
/** Returns the active Release identity, or null for BUILTIN/legacy state. */
|
|
344
|
-
getReleaseId,
|
|
345
|
-
|
|
346
349
|
/**
|
|
347
350
|
* Fetches the current manifest for the active bundle.
|
|
348
351
|
*/
|
|
@@ -448,7 +451,7 @@ function createHotUpdaterClient() {
|
|
|
448
451
|
|
|
449
452
|
const mergedConfig: InternalCheckForUpdateOptions = {
|
|
450
453
|
...config,
|
|
451
|
-
|
|
454
|
+
insights: globalConfig.insights,
|
|
452
455
|
client,
|
|
453
456
|
requestHeaders: {
|
|
454
457
|
...globalConfig.requestHeaders,
|
|
@@ -466,8 +469,6 @@ function createHotUpdaterClient() {
|
|
|
466
469
|
*
|
|
467
470
|
* @param {UpdateBundleParams} params - Parameters object required for bundle update
|
|
468
471
|
* @param {string} params.bundleId - The bundle ID of the app
|
|
469
|
-
* @param {string|null} params.fileUrl - The URL of the zip file
|
|
470
|
-
*
|
|
471
472
|
* @returns {Promise<boolean>} Whether the update was successful
|
|
472
473
|
*
|
|
473
474
|
* @example
|
|
@@ -491,9 +492,34 @@ function createHotUpdaterClient() {
|
|
|
491
492
|
* }
|
|
492
493
|
* ```
|
|
493
494
|
*/
|
|
494
|
-
updateBundle: (params: UpdateParams) => {
|
|
495
|
-
ensureGlobalClient("updateBundle");
|
|
496
|
-
|
|
495
|
+
updateBundle: async (params: UpdateParams) => {
|
|
496
|
+
const client = ensureGlobalClient("updateBundle");
|
|
497
|
+
const fromBundleId = getBundleId();
|
|
498
|
+
const state = getActiveUpdateState();
|
|
499
|
+
const active = state.activeSelection;
|
|
500
|
+
const downloaded = await updateBundle(params);
|
|
501
|
+
if (downloaded) {
|
|
502
|
+
const selection = getActiveUpdateState().activeSelection;
|
|
503
|
+
await reportBundleDownloaded(
|
|
504
|
+
{ ...globalConfig, client },
|
|
505
|
+
{
|
|
506
|
+
fromBundleId,
|
|
507
|
+
fromReleaseId:
|
|
508
|
+
active?.bundleId === fromBundleId
|
|
509
|
+
? active.releaseId
|
|
510
|
+
: state.stableSelection?.bundleId === fromBundleId
|
|
511
|
+
? state.stableSelection.releaseId
|
|
512
|
+
: null,
|
|
513
|
+
toBundleId: params.bundleId,
|
|
514
|
+
toReleaseId: selection?.releaseId ?? null,
|
|
515
|
+
channel: params.channel ?? getChannel(),
|
|
516
|
+
updateStrategy: selection?.scopeKey?.startsWith("v1:fingerprint:")
|
|
517
|
+
? "fingerprint"
|
|
518
|
+
: "appVersion",
|
|
519
|
+
},
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
return downloaded;
|
|
497
523
|
},
|
|
498
524
|
|
|
499
525
|
/**
|
|
@@ -507,10 +533,8 @@ function createHotUpdaterClient() {
|
|
|
507
533
|
hotUpdaterStore.setState({
|
|
508
534
|
artifactType: null,
|
|
509
535
|
details: null,
|
|
510
|
-
downloadedBytes: undefined,
|
|
511
536
|
isUpdateDownloaded: false,
|
|
512
537
|
progress: 0,
|
|
513
|
-
totalBytes: undefined,
|
|
514
538
|
});
|
|
515
539
|
}
|
|
516
540
|
return ok;
|