@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.
Files changed (240) hide show
  1. package/lib/commonjs/checkForUpdate.js +7 -9
  2. package/lib/commonjs/checkForUpdate.js.map +1 -1
  3. package/lib/commonjs/clientPlugin.js +7 -43
  4. package/lib/commonjs/clientPlugin.js.map +1 -1
  5. package/lib/commonjs/httpClient.js +7 -9
  6. package/lib/commonjs/httpClient.js.map +1 -1
  7. package/lib/commonjs/index.js +10 -0
  8. package/lib/commonjs/index.js.map +1 -1
  9. package/lib/commonjs/native.js +4 -4
  10. package/lib/commonjs/native.js.map +1 -1
  11. package/lib/commonjs/pluginHost.js +26 -190
  12. package/lib/commonjs/pluginHost.js.map +1 -1
  13. package/lib/commonjs/releaseCatalogCache.js +7 -59
  14. package/lib/commonjs/releaseCatalogCache.js.map +1 -1
  15. package/lib/commonjs/sdkVersion.js +1 -1
  16. package/lib/module/checkForUpdate.js +1 -3
  17. package/lib/module/checkForUpdate.js.map +1 -1
  18. package/lib/module/clientPlugin.js +1 -41
  19. package/lib/module/clientPlugin.js.map +1 -1
  20. package/lib/module/httpClient.js +1 -3
  21. package/lib/module/httpClient.js.map +1 -1
  22. package/lib/module/index.js +2 -0
  23. package/lib/module/index.js.map +1 -1
  24. package/lib/module/native.js +1 -1
  25. package/lib/module/native.js.map +1 -1
  26. package/lib/module/pluginHost.js +22 -187
  27. package/lib/module/pluginHost.js.map +1 -1
  28. package/lib/module/releaseCatalogCache.js +3 -54
  29. package/lib/module/releaseCatalogCache.js.map +1 -1
  30. package/lib/module/sdkVersion.js +1 -1
  31. package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
  32. package/lib/typescript/commonjs/clientPlugin.d.ts +1 -184
  33. package/lib/typescript/commonjs/clientPlugin.d.ts.map +1 -1
  34. package/lib/typescript/commonjs/httpClient.d.ts +1 -2
  35. package/lib/typescript/commonjs/httpClient.d.ts.map +1 -1
  36. package/lib/typescript/commonjs/index.d.ts +1 -0
  37. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  38. package/lib/typescript/commonjs/native.d.ts +1 -1
  39. package/lib/typescript/commonjs/native.d.ts.map +1 -1
  40. package/lib/typescript/commonjs/pluginHost.d.ts +3 -28
  41. package/lib/typescript/commonjs/pluginHost.d.ts.map +1 -1
  42. package/lib/typescript/commonjs/releaseCatalogCache.d.ts +1 -13
  43. package/lib/typescript/commonjs/releaseCatalogCache.d.ts.map +1 -1
  44. package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
  45. package/lib/typescript/commonjs/types.d.ts +1 -1
  46. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  47. package/lib/typescript/commonjs/wrap.types.d.ts +2 -2
  48. package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
  49. package/lib/typescript/module/clientPlugin.d.ts +1 -184
  50. package/lib/typescript/module/clientPlugin.d.ts.map +1 -1
  51. package/lib/typescript/module/httpClient.d.ts +1 -2
  52. package/lib/typescript/module/httpClient.d.ts.map +1 -1
  53. package/lib/typescript/module/index.d.ts +1 -0
  54. package/lib/typescript/module/index.d.ts.map +1 -1
  55. package/lib/typescript/module/native.d.ts +1 -1
  56. package/lib/typescript/module/native.d.ts.map +1 -1
  57. package/lib/typescript/module/pluginHost.d.ts +3 -28
  58. package/lib/typescript/module/pluginHost.d.ts.map +1 -1
  59. package/lib/typescript/module/releaseCatalogCache.d.ts +1 -13
  60. package/lib/typescript/module/releaseCatalogCache.d.ts.map +1 -1
  61. package/lib/typescript/module/sdkVersion.d.ts +1 -1
  62. package/lib/typescript/module/types.d.ts +1 -1
  63. package/lib/typescript/module/types.d.ts.map +1 -1
  64. package/lib/typescript/module/wrap.types.d.ts +2 -2
  65. package/package.json +7 -16
  66. package/src/checkForUpdate.ts +4 -6
  67. package/src/clientPlugin.ts +17 -231
  68. package/src/httpClient.ts +4 -4
  69. package/src/index.ts +7 -0
  70. package/src/native.ts +1 -1
  71. package/src/pluginHost.ts +24 -241
  72. package/src/releaseCatalogCache.ts +7 -136
  73. package/src/sdkVersion.ts +1 -1
  74. package/src/types.ts +1 -1
  75. package/src/wrap.types.ts +2 -2
  76. package/android/src/test/java/com/hotupdater/BsdiffPatchTest.kt +0 -46
  77. package/android/src/test/java/com/hotupdater/BundleFileStorageServiceTest.kt +0 -2236
  78. package/android/src/test/java/com/hotupdater/HotUpdaterExceptionTest.kt +0 -220
  79. package/android/src/test/java/com/hotupdater/HotUpdaterImplTest.kt +0 -264
  80. package/android/src/test/java/com/hotupdater/HotUpdaterRecoveryStateTest.kt +0 -97
  81. package/android/src/test/java/com/hotupdater/InstallIdentityServiceTest.kt +0 -71
  82. package/android/src/test/java/com/hotupdater/KeyValueStorageServiceTest.kt +0 -106
  83. package/android/src/test/java/com/hotupdater/NativeConfigUtilsTest.kt +0 -20
  84. package/android/src/test/java/com/hotupdater/NoBackupContext.kt +0 -11
  85. package/android/src/test/java/com/hotupdater/OkHttpDownloadServiceTest.kt +0 -397
  86. package/android/src/test/java/com/hotupdater/PendingCrashRecoveryTest.kt +0 -44
  87. package/android/src/test/java/com/hotupdater/PreviousProcessExitTest.kt +0 -57
  88. package/android/src/test/java/com/hotupdater/RelativePathResolverTest.kt +0 -41
  89. package/android/src/test/java/com/hotupdater/ReleaseCatalogCacheServiceTest.kt +0 -118
  90. package/android/src/test/java/com/hotupdater/TarBrArchiveExtractorTest.kt +0 -206
  91. package/lib/commonjs/appReady.spec.js +0 -360
  92. package/lib/commonjs/appReady.spec.js.map +0 -1
  93. package/lib/commonjs/appReady.test-utils.js +0 -25
  94. package/lib/commonjs/appReady.test-utils.js.map +0 -1
  95. package/lib/commonjs/baseURL.js +0 -16
  96. package/lib/commonjs/baseURL.js.map +0 -1
  97. package/lib/commonjs/catalogCacheNative.spec.js +0 -31
  98. package/lib/commonjs/catalogCacheNative.spec.js.map +0 -1
  99. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js +0 -936
  100. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js.map +0 -1
  101. package/lib/commonjs/entryImportGraph.spec.js +0 -50
  102. package/lib/commonjs/entryImportGraph.spec.js.map +0 -1
  103. package/lib/commonjs/httpClient.spec.js +0 -171
  104. package/lib/commonjs/httpClient.spec.js.map +0 -1
  105. package/lib/commonjs/index.spec.js +0 -395
  106. package/lib/commonjs/index.spec.js.map +0 -1
  107. package/lib/commonjs/iosInterop.spec.js +0 -18
  108. package/lib/commonjs/iosInterop.spec.js.map +0 -1
  109. package/lib/commonjs/native.spec.js +0 -910
  110. package/lib/commonjs/native.spec.js.map +0 -1
  111. package/lib/commonjs/pluginHost.spec.js +0 -292
  112. package/lib/commonjs/pluginHost.spec.js.map +0 -1
  113. package/lib/commonjs/plugins/insights/eventId.js +0 -129
  114. package/lib/commonjs/plugins/insights/eventId.js.map +0 -1
  115. package/lib/commonjs/plugins/insights/eventId.spec.js +0 -47
  116. package/lib/commonjs/plugins/insights/eventId.spec.js.map +0 -1
  117. package/lib/commonjs/plugins/insights/index.js +0 -272
  118. package/lib/commonjs/plugins/insights/index.js.map +0 -1
  119. package/lib/commonjs/plugins/insights/insights.spec.js +0 -640
  120. package/lib/commonjs/plugins/insights/insights.spec.js.map +0 -1
  121. package/lib/commonjs/plugins/insights/sender.js +0 -128
  122. package/lib/commonjs/plugins/insights/sender.js.map +0 -1
  123. package/lib/commonjs/plugins/insights/sender.spec.js +0 -265
  124. package/lib/commonjs/plugins/insights/sender.spec.js.map +0 -1
  125. package/lib/commonjs/plugins/insights/state.js +0 -145
  126. package/lib/commonjs/plugins/insights/state.js.map +0 -1
  127. package/lib/commonjs/releaseCatalogCache.spec.js +0 -213
  128. package/lib/commonjs/releaseCatalogCache.spec.js.map +0 -1
  129. package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js +0 -64
  130. package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js.map +0 -1
  131. package/lib/commonjs/store.notification.spec.js +0 -84
  132. package/lib/commonjs/store.notification.spec.js.map +0 -1
  133. package/lib/commonjs/store.spec.js +0 -182
  134. package/lib/commonjs/store.spec.js.map +0 -1
  135. package/lib/commonjs/updateError.spec.js +0 -149
  136. package/lib/commonjs/updateError.spec.js.map +0 -1
  137. package/lib/commonjs/wrap.progress.spec.js +0 -195
  138. package/lib/commonjs/wrap.progress.spec.js.map +0 -1
  139. package/lib/commonjs/wrap.spec.js +0 -232
  140. package/lib/commonjs/wrap.spec.js.map +0 -1
  141. package/lib/module/appReady.spec.js +0 -359
  142. package/lib/module/appReady.spec.js.map +0 -1
  143. package/lib/module/appReady.test-utils.js +0 -19
  144. package/lib/module/appReady.test-utils.js.map +0 -1
  145. package/lib/module/baseURL.js +0 -11
  146. package/lib/module/baseURL.js.map +0 -1
  147. package/lib/module/catalogCacheNative.spec.js +0 -31
  148. package/lib/module/catalogCacheNative.spec.js.map +0 -1
  149. package/lib/module/checkForUpdate.releaseCatalog.spec.js +0 -935
  150. package/lib/module/checkForUpdate.releaseCatalog.spec.js.map +0 -1
  151. package/lib/module/entryImportGraph.spec.js +0 -50
  152. package/lib/module/entryImportGraph.spec.js.map +0 -1
  153. package/lib/module/httpClient.spec.js +0 -171
  154. package/lib/module/httpClient.spec.js.map +0 -1
  155. package/lib/module/index.spec.js +0 -394
  156. package/lib/module/index.spec.js.map +0 -1
  157. package/lib/module/iosInterop.spec.js +0 -18
  158. package/lib/module/iosInterop.spec.js.map +0 -1
  159. package/lib/module/native.spec.js +0 -909
  160. package/lib/module/native.spec.js.map +0 -1
  161. package/lib/module/pluginHost.spec.js +0 -291
  162. package/lib/module/pluginHost.spec.js.map +0 -1
  163. package/lib/module/plugins/insights/eventId.js +0 -122
  164. package/lib/module/plugins/insights/eventId.js.map +0 -1
  165. package/lib/module/plugins/insights/eventId.spec.js +0 -47
  166. package/lib/module/plugins/insights/eventId.spec.js.map +0 -1
  167. package/lib/module/plugins/insights/index.js +0 -268
  168. package/lib/module/plugins/insights/index.js.map +0 -1
  169. package/lib/module/plugins/insights/insights.spec.js +0 -639
  170. package/lib/module/plugins/insights/insights.spec.js.map +0 -1
  171. package/lib/module/plugins/insights/sender.js +0 -123
  172. package/lib/module/plugins/insights/sender.js.map +0 -1
  173. package/lib/module/plugins/insights/sender.spec.js +0 -265
  174. package/lib/module/plugins/insights/sender.spec.js.map +0 -1
  175. package/lib/module/plugins/insights/state.js +0 -139
  176. package/lib/module/plugins/insights/state.js.map +0 -1
  177. package/lib/module/releaseCatalogCache.spec.js +0 -213
  178. package/lib/module/releaseCatalogCache.spec.js.map +0 -1
  179. package/lib/module/releaseCatalogCacheNativeContract.spec.js +0 -64
  180. package/lib/module/releaseCatalogCacheNativeContract.spec.js.map +0 -1
  181. package/lib/module/store.notification.spec.js +0 -85
  182. package/lib/module/store.notification.spec.js.map +0 -1
  183. package/lib/module/store.spec.js +0 -181
  184. package/lib/module/store.spec.js.map +0 -1
  185. package/lib/module/updateError.spec.js +0 -149
  186. package/lib/module/updateError.spec.js.map +0 -1
  187. package/lib/module/wrap.progress.spec.js +0 -196
  188. package/lib/module/wrap.progress.spec.js.map +0 -1
  189. package/lib/module/wrap.spec.js +0 -233
  190. package/lib/module/wrap.spec.js.map +0 -1
  191. package/lib/typescript/commonjs/appReady.test-utils.d.ts +0 -9
  192. package/lib/typescript/commonjs/appReady.test-utils.d.ts.map +0 -1
  193. package/lib/typescript/commonjs/baseURL.d.ts +0 -4
  194. package/lib/typescript/commonjs/baseURL.d.ts.map +0 -1
  195. package/lib/typescript/commonjs/plugins/insights/eventId.d.ts +0 -18
  196. package/lib/typescript/commonjs/plugins/insights/eventId.d.ts.map +0 -1
  197. package/lib/typescript/commonjs/plugins/insights/index.d.ts +0 -40
  198. package/lib/typescript/commonjs/plugins/insights/index.d.ts.map +0 -1
  199. package/lib/typescript/commonjs/plugins/insights/sender.d.ts +0 -74
  200. package/lib/typescript/commonjs/plugins/insights/sender.d.ts.map +0 -1
  201. package/lib/typescript/commonjs/plugins/insights/state.d.ts +0 -46
  202. package/lib/typescript/commonjs/plugins/insights/state.d.ts.map +0 -1
  203. package/lib/typescript/module/appReady.test-utils.d.ts +0 -9
  204. package/lib/typescript/module/appReady.test-utils.d.ts.map +0 -1
  205. package/lib/typescript/module/baseURL.d.ts +0 -4
  206. package/lib/typescript/module/baseURL.d.ts.map +0 -1
  207. package/lib/typescript/module/plugins/insights/eventId.d.ts +0 -18
  208. package/lib/typescript/module/plugins/insights/eventId.d.ts.map +0 -1
  209. package/lib/typescript/module/plugins/insights/index.d.ts +0 -40
  210. package/lib/typescript/module/plugins/insights/index.d.ts.map +0 -1
  211. package/lib/typescript/module/plugins/insights/sender.d.ts +0 -74
  212. package/lib/typescript/module/plugins/insights/sender.d.ts.map +0 -1
  213. package/lib/typescript/module/plugins/insights/state.d.ts +0 -46
  214. package/lib/typescript/module/plugins/insights/state.d.ts.map +0 -1
  215. package/plugins/insights/package.json +0 -8
  216. package/src/appReady.spec.ts +0 -393
  217. package/src/appReady.test-utils.ts +0 -31
  218. package/src/baseURL.ts +0 -15
  219. package/src/catalogCacheNative.spec.ts +0 -63
  220. package/src/checkForUpdate.releaseCatalog.spec.ts +0 -966
  221. package/src/entryImportGraph.spec.ts +0 -65
  222. package/src/httpClient.spec.ts +0 -216
  223. package/src/index.spec.ts +0 -434
  224. package/src/iosInterop.spec.ts +0 -30
  225. package/src/native.spec.ts +0 -978
  226. package/src/pluginHost.spec.ts +0 -297
  227. package/src/plugins/insights/eventId.spec.ts +0 -60
  228. package/src/plugins/insights/eventId.ts +0 -171
  229. package/src/plugins/insights/index.ts +0 -367
  230. package/src/plugins/insights/insights.spec.ts +0 -732
  231. package/src/plugins/insights/sender.spec.ts +0 -287
  232. package/src/plugins/insights/sender.ts +0 -221
  233. package/src/plugins/insights/state.ts +0 -184
  234. package/src/releaseCatalogCache.spec.ts +0 -304
  235. package/src/releaseCatalogCacheNativeContract.spec.ts +0 -80
  236. package/src/store.notification.spec.ts +0 -102
  237. package/src/store.spec.ts +0 -215
  238. package/src/updateError.spec.ts +0 -144
  239. package/src/wrap.progress.spec.ts +0 -232
  240. 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
- };