@hot-updater/react-native 1.0.0-rc.17 → 1.0.0-rc.21
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/lib/commonjs/checkForUpdate.js +7 -9
- package/lib/commonjs/checkForUpdate.js.map +1 -1
- package/lib/commonjs/clientPlugin.js +7 -43
- package/lib/commonjs/clientPlugin.js.map +1 -1
- package/lib/commonjs/httpClient.js +7 -9
- package/lib/commonjs/httpClient.js.map +1 -1
- package/lib/commonjs/index.js +10 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/native.js +4 -4
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/pluginHost.js +26 -190
- package/lib/commonjs/pluginHost.js.map +1 -1
- package/lib/commonjs/releaseCatalogCache.js +7 -59
- package/lib/commonjs/releaseCatalogCache.js.map +1 -1
- package/lib/commonjs/sdkVersion.js +1 -1
- package/lib/module/checkForUpdate.js +1 -3
- package/lib/module/checkForUpdate.js.map +1 -1
- package/lib/module/clientPlugin.js +1 -41
- package/lib/module/clientPlugin.js.map +1 -1
- package/lib/module/httpClient.js +1 -3
- package/lib/module/httpClient.js.map +1 -1
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/native.js +1 -1
- package/lib/module/native.js.map +1 -1
- package/lib/module/pluginHost.js +22 -187
- package/lib/module/pluginHost.js.map +1 -1
- package/lib/module/releaseCatalogCache.js +3 -54
- package/lib/module/releaseCatalogCache.js.map +1 -1
- package/lib/module/sdkVersion.js +1 -1
- package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/commonjs/clientPlugin.d.ts +1 -184
- package/lib/typescript/commonjs/clientPlugin.d.ts.map +1 -1
- package/lib/typescript/commonjs/httpClient.d.ts +1 -2
- package/lib/typescript/commonjs/httpClient.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +1 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/native.d.ts +1 -1
- package/lib/typescript/commonjs/native.d.ts.map +1 -1
- package/lib/typescript/commonjs/pluginHost.d.ts +3 -28
- package/lib/typescript/commonjs/pluginHost.d.ts.map +1 -1
- package/lib/typescript/commonjs/releaseCatalogCache.d.ts +1 -13
- package/lib/typescript/commonjs/releaseCatalogCache.d.ts.map +1 -1
- package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
- package/lib/typescript/commonjs/types.d.ts +1 -1
- package/lib/typescript/commonjs/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/wrap.types.d.ts +2 -2
- package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/module/clientPlugin.d.ts +1 -184
- package/lib/typescript/module/clientPlugin.d.ts.map +1 -1
- package/lib/typescript/module/httpClient.d.ts +1 -2
- package/lib/typescript/module/httpClient.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +1 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/native.d.ts +1 -1
- package/lib/typescript/module/native.d.ts.map +1 -1
- package/lib/typescript/module/pluginHost.d.ts +3 -28
- package/lib/typescript/module/pluginHost.d.ts.map +1 -1
- package/lib/typescript/module/releaseCatalogCache.d.ts +1 -13
- package/lib/typescript/module/releaseCatalogCache.d.ts.map +1 -1
- package/lib/typescript/module/sdkVersion.d.ts +1 -1
- package/lib/typescript/module/types.d.ts +1 -1
- package/lib/typescript/module/types.d.ts.map +1 -1
- package/lib/typescript/module/wrap.types.d.ts +2 -2
- package/package.json +7 -16
- package/src/checkForUpdate.ts +4 -6
- package/src/clientPlugin.ts +17 -231
- package/src/httpClient.ts +4 -4
- package/src/index.ts +7 -0
- package/src/native.ts +1 -1
- package/src/pluginHost.ts +24 -241
- package/src/releaseCatalogCache.ts +7 -136
- package/src/sdkVersion.ts +1 -1
- package/src/types.ts +1 -1
- package/src/wrap.types.ts +2 -2
- package/android/src/test/java/com/hotupdater/BsdiffPatchTest.kt +0 -46
- package/android/src/test/java/com/hotupdater/BundleFileStorageServiceTest.kt +0 -2236
- package/android/src/test/java/com/hotupdater/HotUpdaterExceptionTest.kt +0 -220
- package/android/src/test/java/com/hotupdater/HotUpdaterImplTest.kt +0 -264
- package/android/src/test/java/com/hotupdater/HotUpdaterRecoveryStateTest.kt +0 -97
- package/android/src/test/java/com/hotupdater/InstallIdentityServiceTest.kt +0 -71
- package/android/src/test/java/com/hotupdater/KeyValueStorageServiceTest.kt +0 -106
- package/android/src/test/java/com/hotupdater/NativeConfigUtilsTest.kt +0 -20
- package/android/src/test/java/com/hotupdater/NoBackupContext.kt +0 -11
- package/android/src/test/java/com/hotupdater/OkHttpDownloadServiceTest.kt +0 -397
- package/android/src/test/java/com/hotupdater/PendingCrashRecoveryTest.kt +0 -44
- package/android/src/test/java/com/hotupdater/PreviousProcessExitTest.kt +0 -57
- package/android/src/test/java/com/hotupdater/RelativePathResolverTest.kt +0 -41
- package/android/src/test/java/com/hotupdater/ReleaseCatalogCacheServiceTest.kt +0 -118
- package/android/src/test/java/com/hotupdater/TarBrArchiveExtractorTest.kt +0 -206
- package/lib/commonjs/appReady.spec.js +0 -360
- package/lib/commonjs/appReady.spec.js.map +0 -1
- package/lib/commonjs/appReady.test-utils.js +0 -25
- package/lib/commonjs/appReady.test-utils.js.map +0 -1
- package/lib/commonjs/baseURL.js +0 -16
- package/lib/commonjs/baseURL.js.map +0 -1
- package/lib/commonjs/catalogCacheNative.spec.js +0 -31
- package/lib/commonjs/catalogCacheNative.spec.js.map +0 -1
- package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js +0 -936
- package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js.map +0 -1
- package/lib/commonjs/entryImportGraph.spec.js +0 -50
- package/lib/commonjs/entryImportGraph.spec.js.map +0 -1
- package/lib/commonjs/httpClient.spec.js +0 -171
- package/lib/commonjs/httpClient.spec.js.map +0 -1
- package/lib/commonjs/index.spec.js +0 -395
- package/lib/commonjs/index.spec.js.map +0 -1
- package/lib/commonjs/iosInterop.spec.js +0 -18
- package/lib/commonjs/iosInterop.spec.js.map +0 -1
- package/lib/commonjs/native.spec.js +0 -910
- package/lib/commonjs/native.spec.js.map +0 -1
- package/lib/commonjs/pluginHost.spec.js +0 -292
- package/lib/commonjs/pluginHost.spec.js.map +0 -1
- package/lib/commonjs/plugins/insights/eventId.js +0 -129
- package/lib/commonjs/plugins/insights/eventId.js.map +0 -1
- package/lib/commonjs/plugins/insights/eventId.spec.js +0 -47
- package/lib/commonjs/plugins/insights/eventId.spec.js.map +0 -1
- package/lib/commonjs/plugins/insights/index.js +0 -272
- package/lib/commonjs/plugins/insights/index.js.map +0 -1
- package/lib/commonjs/plugins/insights/insights.spec.js +0 -640
- package/lib/commonjs/plugins/insights/insights.spec.js.map +0 -1
- package/lib/commonjs/plugins/insights/sender.js +0 -128
- package/lib/commonjs/plugins/insights/sender.js.map +0 -1
- package/lib/commonjs/plugins/insights/sender.spec.js +0 -265
- package/lib/commonjs/plugins/insights/sender.spec.js.map +0 -1
- package/lib/commonjs/plugins/insights/state.js +0 -145
- package/lib/commonjs/plugins/insights/state.js.map +0 -1
- package/lib/commonjs/releaseCatalogCache.spec.js +0 -213
- package/lib/commonjs/releaseCatalogCache.spec.js.map +0 -1
- package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js +0 -64
- package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js.map +0 -1
- package/lib/commonjs/store.notification.spec.js +0 -84
- package/lib/commonjs/store.notification.spec.js.map +0 -1
- package/lib/commonjs/store.spec.js +0 -182
- package/lib/commonjs/store.spec.js.map +0 -1
- package/lib/commonjs/updateError.spec.js +0 -149
- package/lib/commonjs/updateError.spec.js.map +0 -1
- package/lib/commonjs/wrap.progress.spec.js +0 -195
- package/lib/commonjs/wrap.progress.spec.js.map +0 -1
- package/lib/commonjs/wrap.spec.js +0 -232
- package/lib/commonjs/wrap.spec.js.map +0 -1
- package/lib/module/appReady.spec.js +0 -359
- package/lib/module/appReady.spec.js.map +0 -1
- package/lib/module/appReady.test-utils.js +0 -19
- package/lib/module/appReady.test-utils.js.map +0 -1
- package/lib/module/baseURL.js +0 -11
- package/lib/module/baseURL.js.map +0 -1
- package/lib/module/catalogCacheNative.spec.js +0 -31
- package/lib/module/catalogCacheNative.spec.js.map +0 -1
- package/lib/module/checkForUpdate.releaseCatalog.spec.js +0 -935
- package/lib/module/checkForUpdate.releaseCatalog.spec.js.map +0 -1
- package/lib/module/entryImportGraph.spec.js +0 -50
- package/lib/module/entryImportGraph.spec.js.map +0 -1
- package/lib/module/httpClient.spec.js +0 -171
- package/lib/module/httpClient.spec.js.map +0 -1
- package/lib/module/index.spec.js +0 -394
- package/lib/module/index.spec.js.map +0 -1
- package/lib/module/iosInterop.spec.js +0 -18
- package/lib/module/iosInterop.spec.js.map +0 -1
- package/lib/module/native.spec.js +0 -909
- package/lib/module/native.spec.js.map +0 -1
- package/lib/module/pluginHost.spec.js +0 -291
- package/lib/module/pluginHost.spec.js.map +0 -1
- package/lib/module/plugins/insights/eventId.js +0 -122
- package/lib/module/plugins/insights/eventId.js.map +0 -1
- package/lib/module/plugins/insights/eventId.spec.js +0 -47
- package/lib/module/plugins/insights/eventId.spec.js.map +0 -1
- package/lib/module/plugins/insights/index.js +0 -268
- package/lib/module/plugins/insights/index.js.map +0 -1
- package/lib/module/plugins/insights/insights.spec.js +0 -639
- package/lib/module/plugins/insights/insights.spec.js.map +0 -1
- package/lib/module/plugins/insights/sender.js +0 -123
- package/lib/module/plugins/insights/sender.js.map +0 -1
- package/lib/module/plugins/insights/sender.spec.js +0 -265
- package/lib/module/plugins/insights/sender.spec.js.map +0 -1
- package/lib/module/plugins/insights/state.js +0 -139
- package/lib/module/plugins/insights/state.js.map +0 -1
- package/lib/module/releaseCatalogCache.spec.js +0 -213
- package/lib/module/releaseCatalogCache.spec.js.map +0 -1
- package/lib/module/releaseCatalogCacheNativeContract.spec.js +0 -64
- package/lib/module/releaseCatalogCacheNativeContract.spec.js.map +0 -1
- package/lib/module/store.notification.spec.js +0 -85
- package/lib/module/store.notification.spec.js.map +0 -1
- package/lib/module/store.spec.js +0 -181
- package/lib/module/store.spec.js.map +0 -1
- package/lib/module/updateError.spec.js +0 -149
- package/lib/module/updateError.spec.js.map +0 -1
- package/lib/module/wrap.progress.spec.js +0 -196
- package/lib/module/wrap.progress.spec.js.map +0 -1
- package/lib/module/wrap.spec.js +0 -233
- package/lib/module/wrap.spec.js.map +0 -1
- package/lib/typescript/commonjs/appReady.test-utils.d.ts +0 -9
- package/lib/typescript/commonjs/appReady.test-utils.d.ts.map +0 -1
- package/lib/typescript/commonjs/baseURL.d.ts +0 -4
- package/lib/typescript/commonjs/baseURL.d.ts.map +0 -1
- package/lib/typescript/commonjs/plugins/insights/eventId.d.ts +0 -18
- package/lib/typescript/commonjs/plugins/insights/eventId.d.ts.map +0 -1
- package/lib/typescript/commonjs/plugins/insights/index.d.ts +0 -40
- package/lib/typescript/commonjs/plugins/insights/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/plugins/insights/sender.d.ts +0 -74
- package/lib/typescript/commonjs/plugins/insights/sender.d.ts.map +0 -1
- package/lib/typescript/commonjs/plugins/insights/state.d.ts +0 -46
- package/lib/typescript/commonjs/plugins/insights/state.d.ts.map +0 -1
- package/lib/typescript/module/appReady.test-utils.d.ts +0 -9
- package/lib/typescript/module/appReady.test-utils.d.ts.map +0 -1
- package/lib/typescript/module/baseURL.d.ts +0 -4
- package/lib/typescript/module/baseURL.d.ts.map +0 -1
- package/lib/typescript/module/plugins/insights/eventId.d.ts +0 -18
- package/lib/typescript/module/plugins/insights/eventId.d.ts.map +0 -1
- package/lib/typescript/module/plugins/insights/index.d.ts +0 -40
- package/lib/typescript/module/plugins/insights/index.d.ts.map +0 -1
- package/lib/typescript/module/plugins/insights/sender.d.ts +0 -74
- package/lib/typescript/module/plugins/insights/sender.d.ts.map +0 -1
- package/lib/typescript/module/plugins/insights/state.d.ts +0 -46
- package/lib/typescript/module/plugins/insights/state.d.ts.map +0 -1
- package/plugins/insights/package.json +0 -8
- package/src/appReady.spec.ts +0 -393
- package/src/appReady.test-utils.ts +0 -31
- package/src/baseURL.ts +0 -15
- package/src/catalogCacheNative.spec.ts +0 -63
- package/src/checkForUpdate.releaseCatalog.spec.ts +0 -966
- package/src/entryImportGraph.spec.ts +0 -65
- package/src/httpClient.spec.ts +0 -216
- package/src/index.spec.ts +0 -434
- package/src/iosInterop.spec.ts +0 -30
- package/src/native.spec.ts +0 -978
- package/src/pluginHost.spec.ts +0 -297
- package/src/plugins/insights/eventId.spec.ts +0 -60
- package/src/plugins/insights/eventId.ts +0 -171
- package/src/plugins/insights/index.ts +0 -367
- package/src/plugins/insights/insights.spec.ts +0 -732
- package/src/plugins/insights/sender.spec.ts +0 -287
- package/src/plugins/insights/sender.ts +0 -221
- package/src/plugins/insights/state.ts +0 -184
- package/src/releaseCatalogCache.spec.ts +0 -304
- package/src/releaseCatalogCacheNativeContract.spec.ts +0 -80
- package/src/store.notification.spec.ts +0 -102
- package/src/store.spec.ts +0 -215
- package/src/updateError.spec.ts +0 -144
- package/src/wrap.progress.spec.ts +0 -232
- package/src/wrap.spec.ts +0 -262
|
@@ -1,367 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
defineClientPlugin,
|
|
3
|
-
type AppReadyResult,
|
|
4
|
-
type BundleDownloadedInfo,
|
|
5
|
-
type HotUpdaterClientContext,
|
|
6
|
-
type HotUpdaterClientPlugin,
|
|
7
|
-
type UpdateCheckResult,
|
|
8
|
-
type UpdateError,
|
|
9
|
-
} from "../../clientPlugin";
|
|
10
|
-
import { createKeyedUUIDv7, createUUIDv7 } from "./eventId";
|
|
11
|
-
import {
|
|
12
|
-
createInsightsEventSender,
|
|
13
|
-
type InsightsDelivery,
|
|
14
|
-
type InsightsEventBody,
|
|
15
|
-
type InsightsEventSender,
|
|
16
|
-
} from "./sender";
|
|
17
|
-
import {
|
|
18
|
-
createInsightsState,
|
|
19
|
-
type InsightsState,
|
|
20
|
-
type RunningReport,
|
|
21
|
-
utcDay,
|
|
22
|
-
utcDayStart,
|
|
23
|
-
} from "./state";
|
|
24
|
-
|
|
25
|
-
export interface InsightsOptions {
|
|
26
|
-
/**
|
|
27
|
-
* Also report from debug builds (`__DEV__`). Defaults to `false`, so
|
|
28
|
-
* development sessions stay out of production Insights.
|
|
29
|
-
*/
|
|
30
|
-
readonly debug?: boolean;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** The app's own id for the signed-in user, attached to later reports. */
|
|
34
|
-
export interface InsightsUser {
|
|
35
|
-
readonly userId: string | number;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface InsightsPlugin extends HotUpdaterClientPlugin {
|
|
39
|
-
readonly id: "insights";
|
|
40
|
-
/**
|
|
41
|
-
* Attaches the signed-in user's id to later reports, or clears it with
|
|
42
|
-
* `null`. It persists on the device, sends nothing by itself, and can be
|
|
43
|
-
* called before `HotUpdater.init`.
|
|
44
|
-
*/
|
|
45
|
-
setUser(user: InsightsUser | null): void;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
type Movement = Pick<
|
|
49
|
-
InsightsEventBody,
|
|
50
|
-
| "type"
|
|
51
|
-
| "channel"
|
|
52
|
-
| "fromBundleId"
|
|
53
|
-
| "fromReleaseId"
|
|
54
|
-
| "toBundleId"
|
|
55
|
-
| "toReleaseId"
|
|
56
|
-
| "updateStrategy"
|
|
57
|
-
| "metadata"
|
|
58
|
-
>;
|
|
59
|
-
|
|
60
|
-
/** A report the plugin built, with what the gate needs to decide on it. */
|
|
61
|
-
type PendingEvent = {
|
|
62
|
-
readonly body: InsightsEventBody;
|
|
63
|
-
readonly day: string;
|
|
64
|
-
/** For UNCHANGED, UPDATE_APPLIED and RECOVERED: what the report says runs. */
|
|
65
|
-
readonly report: RunningReport | null;
|
|
66
|
-
/** For UPDATE_FAILED: the day's key the failure is reported under. */
|
|
67
|
-
readonly failureKey: string | null;
|
|
68
|
-
/** For UPDATE_FAILED: a later success for its target made it moot. */
|
|
69
|
-
superseded?: boolean;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const normalizeUserId = (user: InsightsUser | null): string | null => {
|
|
73
|
-
if (user === null) return null;
|
|
74
|
-
const userId = String(user.userId).trim();
|
|
75
|
-
return userId.length === 0 ? null : userId;
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Reports update adoption to a server that runs the `insights()` server
|
|
80
|
-
* plugin: launches (at most once a UTC day while nothing changes), downloads,
|
|
81
|
-
* applies, recoveries, and update failures. After the server answers that
|
|
82
|
-
* Insights is off, the plugin sends nothing for 24 hours, and for the rest
|
|
83
|
-
* of that runtime.
|
|
84
|
-
*
|
|
85
|
-
* @example
|
|
86
|
-
* ```ts
|
|
87
|
-
* import { HotUpdater } from "@hot-updater/react-native";
|
|
88
|
-
* import { insights } from "@hot-updater/react-native/plugins/insights";
|
|
89
|
-
*
|
|
90
|
-
* const analytics = insights();
|
|
91
|
-
* HotUpdater.init({ baseURL, plugins: [analytics] });
|
|
92
|
-
* analytics.setUser({ userId: "user-123" });
|
|
93
|
-
* ```
|
|
94
|
-
*/
|
|
95
|
-
export const insights = (options: InsightsOptions = {}): InsightsPlugin => {
|
|
96
|
-
let context: HotUpdaterClientContext | null = null;
|
|
97
|
-
let state: InsightsState | null = null;
|
|
98
|
-
/** A user set before setup, applied once the plugin has storage. */
|
|
99
|
-
let pendingUser: { readonly userId: string | null } | null = null;
|
|
100
|
-
/** A download in this runtime: a later no-change report would hide it. */
|
|
101
|
-
let didDownload = false;
|
|
102
|
-
let lastDownloadedSelection: string | null = null;
|
|
103
|
-
const pending = new Map<InsightsEventBody, PendingEvent>();
|
|
104
|
-
let send: InsightsEventSender | null = null;
|
|
105
|
-
|
|
106
|
-
const createEvent = (
|
|
107
|
-
movement: Movement,
|
|
108
|
-
eventId?: (now: number, installId: string) => string,
|
|
109
|
-
): PendingEvent | null => {
|
|
110
|
-
if (context === null || state === null) return null;
|
|
111
|
-
const appVersion = context.appVersion;
|
|
112
|
-
if (appVersion === null) {
|
|
113
|
-
console.warn(
|
|
114
|
-
`[HotUpdater] Insights needs the native app version; the ${movement.type} event was not sent.`,
|
|
115
|
-
);
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
const now = context.now();
|
|
119
|
-
const installId = context.installId;
|
|
120
|
-
const userId = state.readUserId();
|
|
121
|
-
const body: InsightsEventBody = {
|
|
122
|
-
...movement,
|
|
123
|
-
eventId: eventId?.(now, installId) ?? createUUIDv7(),
|
|
124
|
-
installId,
|
|
125
|
-
...(userId === null ? {} : { userId }),
|
|
126
|
-
platform: context.platform,
|
|
127
|
-
appVersion,
|
|
128
|
-
cohort: context.getCohort(),
|
|
129
|
-
fingerprintHash: context.getFingerprintHash(),
|
|
130
|
-
sdkVersion: context.sdkVersion,
|
|
131
|
-
};
|
|
132
|
-
const day = utcDay(now);
|
|
133
|
-
return {
|
|
134
|
-
body,
|
|
135
|
-
day,
|
|
136
|
-
report:
|
|
137
|
-
movement.type === "UNCHANGED" ||
|
|
138
|
-
movement.type === "UPDATE_APPLIED" ||
|
|
139
|
-
movement.type === "RECOVERED"
|
|
140
|
-
? {
|
|
141
|
-
day,
|
|
142
|
-
channel: movement.channel,
|
|
143
|
-
appVersion,
|
|
144
|
-
bundleId: movement.toBundleId,
|
|
145
|
-
releaseId: movement.toReleaseId,
|
|
146
|
-
userId,
|
|
147
|
-
}
|
|
148
|
-
: null,
|
|
149
|
-
failureKey: null,
|
|
150
|
-
};
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
const enqueue = (event: PendingEvent | null) => {
|
|
154
|
-
if (event === null || send === null) return;
|
|
155
|
-
const { type, toBundleId } = event.body;
|
|
156
|
-
if (type === "UPDATE_DOWNLOADED" || type === "UPDATE_APPLIED") {
|
|
157
|
-
// A failure for a target that then arrived no longer describes it.
|
|
158
|
-
for (const queued of pending.values()) {
|
|
159
|
-
if (
|
|
160
|
-
queued.body.type === "UPDATE_FAILED" &&
|
|
161
|
-
queued.body.toBundleId === toBundleId
|
|
162
|
-
) {
|
|
163
|
-
queued.superseded = true;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
pending.set(event.body, event);
|
|
168
|
-
void send(event.body).catch((error: unknown) => {
|
|
169
|
-
console.warn(
|
|
170
|
-
`[HotUpdater] Insights ${event.body.type} event was not delivered:`,
|
|
171
|
-
error,
|
|
172
|
-
);
|
|
173
|
-
});
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
const reportLaunch = (
|
|
177
|
-
channel: string,
|
|
178
|
-
bundleId: string,
|
|
179
|
-
releaseId: string | null,
|
|
180
|
-
fromReleaseId: string | null,
|
|
181
|
-
) => {
|
|
182
|
-
// After a download the server shows the update as waiting; a later
|
|
183
|
-
// no-change report from this runtime would hide it.
|
|
184
|
-
if (didDownload) return;
|
|
185
|
-
enqueue(
|
|
186
|
-
createEvent({
|
|
187
|
-
type: "UNCHANGED",
|
|
188
|
-
channel,
|
|
189
|
-
fromBundleId: null,
|
|
190
|
-
fromReleaseId,
|
|
191
|
-
toBundleId: bundleId,
|
|
192
|
-
toReleaseId: releaseId,
|
|
193
|
-
updateStrategy: null,
|
|
194
|
-
}),
|
|
195
|
-
);
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
const onAppReady = (result: AppReadyResult) => {
|
|
199
|
-
if (result.status === "UNCHANGED") {
|
|
200
|
-
reportLaunch(result.channel, result.bundleId, result.releaseId, null);
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
enqueue(
|
|
204
|
-
createEvent({
|
|
205
|
-
type: result.status,
|
|
206
|
-
channel: result.channel,
|
|
207
|
-
fromBundleId: result.fromBundleId,
|
|
208
|
-
fromReleaseId: result.fromReleaseId,
|
|
209
|
-
toBundleId: result.toBundleId,
|
|
210
|
-
toReleaseId: result.toReleaseId,
|
|
211
|
-
updateStrategy: result.updateStrategy,
|
|
212
|
-
// Tells a crash from the system or the user closing the app.
|
|
213
|
-
...(result.status === "RECOVERED" && result.previousProcessExit !== null
|
|
214
|
-
? { metadata: { previousProcessExit: result.previousProcessExit } }
|
|
215
|
-
: {}),
|
|
216
|
-
}),
|
|
217
|
-
);
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
const onUpdateCheck = (result: UpdateCheckResult) => {
|
|
221
|
-
if (result.status !== "UNCHANGED") return;
|
|
222
|
-
reportLaunch(
|
|
223
|
-
result.channel,
|
|
224
|
-
result.bundleId,
|
|
225
|
-
result.releaseId,
|
|
226
|
-
result.previousReleaseId === result.releaseId
|
|
227
|
-
? null
|
|
228
|
-
: result.previousReleaseId,
|
|
229
|
-
);
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
const onBundleDownloaded = (info: BundleDownloadedInfo) => {
|
|
233
|
-
const selection = JSON.stringify([
|
|
234
|
-
info.channel,
|
|
235
|
-
info.toReleaseId,
|
|
236
|
-
info.toBundleId,
|
|
237
|
-
]);
|
|
238
|
-
if (lastDownloadedSelection === selection) return;
|
|
239
|
-
lastDownloadedSelection = selection;
|
|
240
|
-
didDownload = true;
|
|
241
|
-
enqueue(
|
|
242
|
-
createEvent({
|
|
243
|
-
type: "UPDATE_DOWNLOADED",
|
|
244
|
-
channel: info.channel,
|
|
245
|
-
fromBundleId: info.fromBundleId,
|
|
246
|
-
fromReleaseId: info.fromReleaseId,
|
|
247
|
-
toBundleId: info.toBundleId,
|
|
248
|
-
toReleaseId: info.toReleaseId,
|
|
249
|
-
updateStrategy: info.updateStrategy,
|
|
250
|
-
metadata: {
|
|
251
|
-
delivery: info.delivery,
|
|
252
|
-
...(info.patchFallback ? { patchFallback: true } : {}),
|
|
253
|
-
},
|
|
254
|
-
}),
|
|
255
|
-
);
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
const onUpdateError = (error: UpdateError) => {
|
|
259
|
-
// A check that could not reach the server means the device is offline,
|
|
260
|
-
// and its report would not arrive either.
|
|
261
|
-
if (error.stage === "check" && error.reason === "network") return;
|
|
262
|
-
const targetBundleId = error.targetBundleId ?? error.bundleId;
|
|
263
|
-
const failureKey = [error.stage, error.reason, targetBundleId].join(" ");
|
|
264
|
-
const event = createEvent(
|
|
265
|
-
{
|
|
266
|
-
type: "UPDATE_FAILED",
|
|
267
|
-
channel: error.channel,
|
|
268
|
-
fromBundleId: error.bundleId,
|
|
269
|
-
fromReleaseId: error.releaseId,
|
|
270
|
-
toBundleId: targetBundleId,
|
|
271
|
-
toReleaseId: error.targetReleaseId ?? null,
|
|
272
|
-
updateStrategy: error.updateStrategy,
|
|
273
|
-
metadata: {
|
|
274
|
-
failure: {
|
|
275
|
-
stage: error.stage,
|
|
276
|
-
reason: error.reason,
|
|
277
|
-
...(error.resource === undefined
|
|
278
|
-
? {}
|
|
279
|
-
: { resource: error.resource }),
|
|
280
|
-
...(error.httpStatus === undefined
|
|
281
|
-
? {}
|
|
282
|
-
: { httpStatus: error.httpStatus }),
|
|
283
|
-
...(error.transport === undefined
|
|
284
|
-
? {}
|
|
285
|
-
: { transport: error.transport }),
|
|
286
|
-
...(error.originCode === undefined
|
|
287
|
-
? {}
|
|
288
|
-
: { originCode: error.originCode }),
|
|
289
|
-
...(error.previousProcessExit === undefined
|
|
290
|
-
? {}
|
|
291
|
-
: { previousProcessExit: error.previousProcessExit }),
|
|
292
|
-
},
|
|
293
|
-
},
|
|
294
|
-
},
|
|
295
|
-
// One id per installation, UTC day, and failure, so the server
|
|
296
|
-
// stores a repeated failure once.
|
|
297
|
-
(now, installId) =>
|
|
298
|
-
createKeyedUUIDv7(
|
|
299
|
-
[installId, utcDay(now), failureKey].join("\n"),
|
|
300
|
-
utcDayStart(now),
|
|
301
|
-
),
|
|
302
|
-
);
|
|
303
|
-
enqueue(event === null ? null : { ...event, failureKey });
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
const admit = (body: InsightsEventBody): boolean => {
|
|
307
|
-
const event = pending.get(body);
|
|
308
|
-
if (event === undefined || state === null || context === null) {
|
|
309
|
-
return false;
|
|
310
|
-
}
|
|
311
|
-
if (event.superseded === true || state.isPaused(context.now())) {
|
|
312
|
-
pending.delete(body);
|
|
313
|
-
return false;
|
|
314
|
-
}
|
|
315
|
-
const admitted =
|
|
316
|
-
body.type === "UNCHANGED"
|
|
317
|
-
? event.report === null || !state.repeatsReport(event.report)
|
|
318
|
-
: body.type === "UPDATE_FAILED"
|
|
319
|
-
? event.failureKey === null ||
|
|
320
|
-
!state.hasFailure(event.day, event.failureKey)
|
|
321
|
-
: true;
|
|
322
|
-
if (!admitted) pending.delete(body);
|
|
323
|
-
return admitted;
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
const settle = (body: InsightsEventBody, delivery: InsightsDelivery) => {
|
|
327
|
-
const event = pending.get(body);
|
|
328
|
-
pending.delete(body);
|
|
329
|
-
if (event === undefined || state === null || context === null) return;
|
|
330
|
-
if (delivery === "failed") return;
|
|
331
|
-
if (delivery === "disabled") {
|
|
332
|
-
state.pause(context.now());
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
if (event.failureKey !== null) {
|
|
336
|
-
state.recordFailure(event.day, event.failureKey);
|
|
337
|
-
}
|
|
338
|
-
if (delivery === "refused") return;
|
|
339
|
-
state.resume();
|
|
340
|
-
if (event.report !== null) state.recordReport(event.report);
|
|
341
|
-
else state.forgetReport();
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
return defineClientPlugin({
|
|
345
|
-
id: "insights",
|
|
346
|
-
setup(pluginContext) {
|
|
347
|
-
context = pluginContext;
|
|
348
|
-
state = createInsightsState(pluginContext.storage);
|
|
349
|
-
if (pendingUser !== null) {
|
|
350
|
-
state.writeUserId(pendingUser.userId);
|
|
351
|
-
pendingUser = null;
|
|
352
|
-
}
|
|
353
|
-
if (pluginContext.isDebugBuild && options.debug !== true) return;
|
|
354
|
-
|
|
355
|
-
send = createInsightsEventSender(pluginContext.fetch, { admit, settle });
|
|
356
|
-
return { onAppReady, onUpdateCheck, onBundleDownloaded, onUpdateError };
|
|
357
|
-
},
|
|
358
|
-
setUser(user) {
|
|
359
|
-
const userId = normalizeUserId(user);
|
|
360
|
-
if (state === null) {
|
|
361
|
-
pendingUser = { userId };
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
state.writeUserId(userId);
|
|
365
|
-
},
|
|
366
|
-
});
|
|
367
|
-
};
|