@hot-updater/react-native 1.0.0-rc.1 → 1.0.0-rc.14

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 (143) hide show
  1. package/android/proguard-rules.pro +15 -0
  2. package/android/src/main/java/com/hotupdater/BundleFileStorageService.kt +1 -1
  3. package/android/src/main/java/com/hotupdater/BundleMetadata.kt +7 -0
  4. package/android/src/main/java/com/hotupdater/HotUpdaterRecoveryManager.kt +37 -54
  5. package/android/src/main/java/com/hotupdater/HotUpdaterRecoveryState.kt +64 -0
  6. package/android/src/test/java/com/hotupdater/HotUpdaterRecoveryStateTest.kt +97 -0
  7. package/android/src/test/java/com/hotupdater/PendingCrashRecoveryTest.kt +44 -0
  8. package/ios/HotUpdater/Internal/HotUpdaterImpl.swift +102 -20
  9. package/ios/HotUpdater/Recovery/HotUpdaterRecovery.h +16 -0
  10. package/ios/HotUpdater/Recovery/HotUpdaterRecovery.mm +83 -0
  11. package/ios/HotUpdater/Recovery/HotUpdaterRecoveryHooks.mm +49 -0
  12. package/lib/commonjs/checkForUpdate.js +25 -13
  13. package/lib/commonjs/checkForUpdate.js.map +1 -1
  14. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js +88 -24
  15. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js.map +1 -1
  16. package/lib/commonjs/httpClient.js +2 -2
  17. package/lib/commonjs/httpClient.js.map +1 -1
  18. package/lib/commonjs/index.js +30 -9
  19. package/lib/commonjs/index.js.map +1 -1
  20. package/lib/commonjs/index.spec.js +56 -11
  21. package/lib/commonjs/index.spec.js.map +1 -1
  22. package/lib/commonjs/native.js +8 -6
  23. package/lib/commonjs/native.js.map +1 -1
  24. package/lib/commonjs/native.spec.js +107 -6
  25. package/lib/commonjs/native.spec.js.map +1 -1
  26. package/lib/commonjs/{notifyAppReadyAnalytics.boundary.spec.js → notifyAppReadyInsights.boundary.spec.js} +21 -21
  27. package/lib/commonjs/notifyAppReadyInsights.boundary.spec.js.map +1 -0
  28. package/lib/commonjs/notifyAppReadyInsights.js +185 -0
  29. package/lib/commonjs/notifyAppReadyInsights.js.map +1 -0
  30. package/lib/commonjs/{notifyAppReadyAnalytics.spec.js → notifyAppReadyInsights.spec.js} +102 -29
  31. package/lib/commonjs/notifyAppReadyInsights.spec.js.map +1 -0
  32. package/lib/commonjs/{notifyAppReadyAnalytics.test-utils.js → notifyAppReadyInsights.test-utils.js} +3 -3
  33. package/lib/commonjs/notifyAppReadyInsights.test-utils.js.map +1 -0
  34. package/lib/commonjs/{notifyAppReadyAnalytics.transport.spec.js → notifyAppReadyInsights.transport.spec.js} +7 -7
  35. package/lib/commonjs/notifyAppReadyInsights.transport.spec.js.map +1 -0
  36. package/lib/commonjs/sdkVersion.js +1 -1
  37. package/lib/commonjs/sdkVersion.js.map +1 -1
  38. package/lib/commonjs/wrap.js +10 -9
  39. package/lib/commonjs/wrap.js.map +1 -1
  40. package/lib/commonjs/wrap.spec.js +90 -25
  41. package/lib/commonjs/wrap.spec.js.map +1 -1
  42. package/lib/module/checkForUpdate.js +25 -13
  43. package/lib/module/checkForUpdate.js.map +1 -1
  44. package/lib/module/checkForUpdate.releaseCatalog.spec.js +88 -24
  45. package/lib/module/checkForUpdate.releaseCatalog.spec.js.map +1 -1
  46. package/lib/module/httpClient.js +2 -2
  47. package/lib/module/httpClient.js.map +1 -1
  48. package/lib/module/index.js +31 -10
  49. package/lib/module/index.js.map +1 -1
  50. package/lib/module/index.spec.js +56 -11
  51. package/lib/module/index.spec.js.map +1 -1
  52. package/lib/module/native.js +6 -4
  53. package/lib/module/native.js.map +1 -1
  54. package/lib/module/native.spec.js +107 -6
  55. package/lib/module/native.spec.js.map +1 -1
  56. package/lib/module/{notifyAppReadyAnalytics.boundary.spec.js → notifyAppReadyInsights.boundary.spec.js} +16 -16
  57. package/lib/module/notifyAppReadyInsights.boundary.spec.js.map +1 -0
  58. package/lib/module/notifyAppReadyInsights.js +178 -0
  59. package/lib/module/notifyAppReadyInsights.js.map +1 -0
  60. package/lib/module/{notifyAppReadyAnalytics.spec.js → notifyAppReadyInsights.spec.js} +94 -21
  61. package/lib/module/notifyAppReadyInsights.spec.js.map +1 -0
  62. package/lib/module/{notifyAppReadyAnalytics.test-utils.js → notifyAppReadyInsights.test-utils.js} +3 -3
  63. package/lib/module/notifyAppReadyInsights.test-utils.js.map +1 -0
  64. package/lib/module/{notifyAppReadyAnalytics.transport.spec.js → notifyAppReadyInsights.transport.spec.js} +4 -4
  65. package/lib/module/notifyAppReadyInsights.transport.spec.js.map +1 -0
  66. package/lib/module/sdkVersion.js +1 -1
  67. package/lib/module/sdkVersion.js.map +1 -1
  68. package/lib/module/wrap.js +10 -9
  69. package/lib/module/wrap.js.map +1 -1
  70. package/lib/module/wrap.spec.js +92 -25
  71. package/lib/module/wrap.spec.js.map +1 -1
  72. package/lib/typescript/commonjs/checkForUpdate.d.ts +1 -1
  73. package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
  74. package/lib/typescript/commonjs/httpClient.d.ts +6 -6
  75. package/lib/typescript/commonjs/httpClient.d.ts.map +1 -1
  76. package/lib/typescript/commonjs/index.d.ts +4 -5
  77. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  78. package/lib/typescript/commonjs/native.d.ts +4 -3
  79. package/lib/typescript/commonjs/native.d.ts.map +1 -1
  80. package/lib/typescript/commonjs/notifyAppReadyInsights.d.ts +25 -0
  81. package/lib/typescript/commonjs/notifyAppReadyInsights.d.ts.map +1 -0
  82. package/lib/typescript/commonjs/notifyAppReadyInsights.test-utils.d.ts +8 -0
  83. package/lib/typescript/commonjs/notifyAppReadyInsights.test-utils.d.ts.map +1 -0
  84. package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
  85. package/lib/typescript/commonjs/sdkVersion.d.ts.map +1 -1
  86. package/lib/typescript/commonjs/wrap.d.ts.map +1 -1
  87. package/lib/typescript/commonjs/wrap.types.d.ts +5 -6
  88. package/lib/typescript/commonjs/wrap.types.d.ts.map +1 -1
  89. package/lib/typescript/module/checkForUpdate.d.ts +1 -1
  90. package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
  91. package/lib/typescript/module/httpClient.d.ts +6 -6
  92. package/lib/typescript/module/httpClient.d.ts.map +1 -1
  93. package/lib/typescript/module/index.d.ts +4 -5
  94. package/lib/typescript/module/index.d.ts.map +1 -1
  95. package/lib/typescript/module/native.d.ts +4 -3
  96. package/lib/typescript/module/native.d.ts.map +1 -1
  97. package/lib/typescript/module/notifyAppReadyInsights.d.ts +25 -0
  98. package/lib/typescript/module/notifyAppReadyInsights.d.ts.map +1 -0
  99. package/lib/typescript/module/notifyAppReadyInsights.test-utils.d.ts +8 -0
  100. package/lib/typescript/module/notifyAppReadyInsights.test-utils.d.ts.map +1 -0
  101. package/lib/typescript/module/sdkVersion.d.ts +1 -1
  102. package/lib/typescript/module/sdkVersion.d.ts.map +1 -1
  103. package/lib/typescript/module/wrap.d.ts.map +1 -1
  104. package/lib/typescript/module/wrap.types.d.ts +5 -6
  105. package/lib/typescript/module/wrap.types.d.ts.map +1 -1
  106. package/package.json +3 -3
  107. package/src/checkForUpdate.releaseCatalog.spec.ts +127 -57
  108. package/src/checkForUpdate.ts +30 -18
  109. package/src/httpClient.ts +11 -11
  110. package/src/index.spec.ts +59 -11
  111. package/src/index.ts +41 -13
  112. package/src/native.spec.ts +110 -6
  113. package/src/native.ts +9 -8
  114. package/src/{notifyAppReadyAnalytics.boundary.spec.ts → notifyAppReadyInsights.boundary.spec.ts} +17 -17
  115. package/src/{notifyAppReadyAnalytics.spec.ts → notifyAppReadyInsights.spec.ts} +81 -22
  116. package/src/{notifyAppReadyAnalytics.test-utils.ts → notifyAppReadyInsights.test-utils.ts} +4 -4
  117. package/src/{notifyAppReadyAnalytics.transport.spec.ts → notifyAppReadyInsights.transport.spec.ts} +5 -5
  118. package/src/notifyAppReadyInsights.ts +281 -0
  119. package/src/sdkVersion.ts +1 -1
  120. package/src/wrap.spec.ts +101 -31
  121. package/src/wrap.tsx +11 -9
  122. package/src/wrap.types.ts +5 -6
  123. package/lib/commonjs/notifyAppReadyAnalytics.boundary.spec.js.map +0 -1
  124. package/lib/commonjs/notifyAppReadyAnalytics.js +0 -133
  125. package/lib/commonjs/notifyAppReadyAnalytics.js.map +0 -1
  126. package/lib/commonjs/notifyAppReadyAnalytics.spec.js.map +0 -1
  127. package/lib/commonjs/notifyAppReadyAnalytics.test-utils.js.map +0 -1
  128. package/lib/commonjs/notifyAppReadyAnalytics.transport.spec.js.map +0 -1
  129. package/lib/module/notifyAppReadyAnalytics.boundary.spec.js.map +0 -1
  130. package/lib/module/notifyAppReadyAnalytics.js +0 -128
  131. package/lib/module/notifyAppReadyAnalytics.js.map +0 -1
  132. package/lib/module/notifyAppReadyAnalytics.spec.js.map +0 -1
  133. package/lib/module/notifyAppReadyAnalytics.test-utils.js.map +0 -1
  134. package/lib/module/notifyAppReadyAnalytics.transport.spec.js.map +0 -1
  135. package/lib/typescript/commonjs/notifyAppReadyAnalytics.d.ts +0 -13
  136. package/lib/typescript/commonjs/notifyAppReadyAnalytics.d.ts.map +0 -1
  137. package/lib/typescript/commonjs/notifyAppReadyAnalytics.test-utils.d.ts +0 -8
  138. package/lib/typescript/commonjs/notifyAppReadyAnalytics.test-utils.d.ts.map +0 -1
  139. package/lib/typescript/module/notifyAppReadyAnalytics.d.ts +0 -13
  140. package/lib/typescript/module/notifyAppReadyAnalytics.d.ts.map +0 -1
  141. package/lib/typescript/module/notifyAppReadyAnalytics.test-utils.d.ts +0 -8
  142. package/lib/typescript/module/notifyAppReadyAnalytics.test-utils.d.ts.map +0 -1
  143. package/src/notifyAppReadyAnalytics.ts +0 -194
@@ -23,9 +23,10 @@ export type HotUpdaterFallbackComponentProps = {
23
23
  interface CommonHotUpdaterOptions {
24
24
  /**
25
25
  * Sends app-ready transitions and same-Bundle Release adoptions to the
26
- * configured server. Omit or set to `false` to disable client reporting.
26
+ * configured server. Defaults to `true`; set to `false` to disable client
27
+ * reporting.
27
28
  */
28
- analytics?: boolean;
29
+ insights?: boolean;
29
30
  /** Base URL of a server exposing the Hot Updater v1 client HTTP protocol. */
30
31
  baseURL: HotUpdaterBaseURL;
31
32
  requestHeaders?: Record<string, string>;
@@ -43,7 +44,7 @@ export type AutoUpdateOptions = CommonHotUpdaterOptions & {
43
44
  export type HotUpdaterInitOptions = CommonHotUpdaterOptions;
44
45
  export type HotUpdaterOptions = AutoUpdateOptions;
45
46
  type InternalCommonOptions = {
46
- analytics?: boolean;
47
+ insights?: boolean;
47
48
  client: HotUpdaterHttpClient;
48
49
  requestHeaders?: Record<string, string>;
49
50
  requestTimeout?: number;
@@ -57,9 +58,7 @@ type InternalAutoUpdateOptions = InternalCommonOptions & {
57
58
  reloadOnForceUpdate?: boolean;
58
59
  onUpdateProcessCompleted?: (response: RunUpdateProcessResponse) => void;
59
60
  };
60
- export type InternalInitOptions = InternalCommonOptions & {
61
- analytics?: boolean;
62
- };
61
+ export type InternalInitOptions = InternalCommonOptions;
63
62
  export type InternalWrapOptions = InternalAutoUpdateOptions;
64
63
  export {};
65
64
  //# sourceMappingURL=wrap.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrap.types.d.ts","sourceRoot":"","sources":["../../../src/wrap.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,YAAY,CAAC;IAC7C,iBAAiB,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,YAAY,GACpB,kBAAkB,GAClB,UAAU,GACV,0BAA0B,CAAC;AAE/B,MAAM,MAAM,gCAAgC,GAAG;IAC7C,MAAM,EAAE,OAAO,CAAC,YAAY,EAAE,0BAA0B,CAAC,CAAC;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,eAAe,CAAC,iBAAiB,CAAC,CAAC;IACpD,UAAU,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,eAAe,CAAC,cAAc,CAAC,CAAC;IAC9C,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;CACrC,CAAC;AAEF,UAAU,uBAAuB;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,OAAO,EAAE,iBAAiB,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC1D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK,GAAG,OAAO,KAAK,IAAI,CAAC;CAC9D;AAED,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,GAAG;IACxD,cAAc,EAAE,aAAa,GAAG,YAAY,CAAC;IAC7C,iBAAiB,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,gCAAgC,CAAC,CAAC;IAC/D,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,wBAAwB,CAAC,EAAE,CAAC,QAAQ,EAAE,wBAAwB,KAAK,IAAI,CAAC;CACzE,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAElD,KAAK,qBAAqB,GAAG;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC1D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK,GAAG,OAAO,KAAK,IAAI,CAAC;CAC9D,CAAC;AAEF,KAAK,yBAAyB,GAAG,qBAAqB,GAAG;IACvD,cAAc,EAAE,aAAa,GAAG,YAAY,CAAC;IAC7C,iBAAiB,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,gCAAgC,CAAC,CAAC;IAC/D,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,wBAAwB,CAAC,EAAE,CAAC,QAAQ,EAAE,wBAAwB,KAAK,IAAI,CAAC;CACzE,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,GAAG;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,yBAAyB,CAAC"}
1
+ {"version":3,"file":"wrap.types.d.ts","sourceRoot":"","sources":["../../../src/wrap.types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hot-updater/react-native",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.14",
4
4
  "description": "React Native OTA solution for self-hosted",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./lib/commonjs/index.js",
@@ -120,8 +120,8 @@
120
120
  },
121
121
  "dependencies": {
122
122
  "use-sync-external-store": "1.5.0",
123
- "@hot-updater/core": "1.0.0-rc.0",
124
- "@hot-updater/plugin-core": "1.0.0-rc.0"
123
+ "@hot-updater/core": "1.0.0-rc.14",
124
+ "@hot-updater/plugin-core": "1.0.0-rc.14"
125
125
  },
126
126
  "scripts": {
127
127
  "build": "node ./scripts/sync-sdk-version.mjs run -- bob build",
@@ -81,20 +81,21 @@ const createClient = (catalog = createCatalog()) => {
81
81
  fileHash: "bundle-hash",
82
82
  fileUrl: "https://updates.example.com/bundle.zip",
83
83
  }));
84
- const sendAnalyticsEvent = vi.fn(async () => undefined);
84
+ const sendInsightsEvent = vi.fn(async () => undefined);
85
85
  const session = {
86
86
  fetchReleaseCatalog,
87
87
  resolveArtifact,
88
- sendAnalyticsEvent,
88
+ sendInsightsEvent,
89
89
  };
90
90
  const client: HotUpdaterHttpClient = {
91
91
  createSession: vi.fn(async () => session),
92
92
  };
93
- return { client, fetchReleaseCatalog, resolveArtifact, sendAnalyticsEvent };
93
+ return { client, fetchReleaseCatalog, resolveArtifact, sendInsightsEvent };
94
94
  };
95
95
 
96
96
  describe("checkForUpdate Release catalog protocol", () => {
97
97
  beforeEach(() => {
98
+ vi.resetModules();
98
99
  vi.clearAllMocks();
99
100
  vi.stubGlobal("__DEV__", false);
100
101
  mocks.acceptReleaseCatalog.mockReturnValue(true);
@@ -109,6 +110,59 @@ describe("checkForUpdate Release catalog protocol", () => {
109
110
  mocks.updateBundle.mockResolvedValue(true);
110
111
  });
111
112
 
113
+ it("reports an optional download only after staging, without treating the target as running", async () => {
114
+ const { checkForUpdate } = await import("./checkForUpdate");
115
+ const { client, sendInsightsEvent } = createClient();
116
+ let complete!: (success: boolean) => void;
117
+ mocks.updateBundle.mockImplementationOnce(
118
+ () =>
119
+ new Promise<boolean>((resolve) => {
120
+ complete = resolve;
121
+ }),
122
+ );
123
+ const update = await checkForUpdate({
124
+ client,
125
+ insights: true,
126
+ updateStrategy: "appVersion",
127
+ });
128
+ expect(update?.shouldForceUpdate).toBe(false);
129
+ const pending = update!.updateBundle();
130
+ await vi.waitFor(() => expect(mocks.updateBundle).toHaveBeenCalledOnce());
131
+ expect(sendInsightsEvent).not.toHaveBeenCalled();
132
+ complete(true);
133
+ await expect(pending).resolves.toBe(true);
134
+ expect(sendInsightsEvent).toHaveBeenCalledExactlyOnceWith(
135
+ expect.objectContaining({
136
+ type: "UPDATE_DOWNLOADED",
137
+ fromBundleId: CURRENT_BUNDLE_ID,
138
+ toBundleId: TARGET_BUNDLE_ID,
139
+ fromReleaseId: null,
140
+ toReleaseId: RELEASE_ID,
141
+ updateStrategy: "appVersion",
142
+ }),
143
+ );
144
+ await update!.updateBundle();
145
+ expect(sendInsightsEvent).toHaveBeenCalledOnce();
146
+ });
147
+
148
+ it.each([false, "failure"])(
149
+ "does not report a download when staging returns %s",
150
+ async (result) => {
151
+ const { checkForUpdate } = await import("./checkForUpdate");
152
+ const { client, sendInsightsEvent } = createClient();
153
+ if (result === false) mocks.updateBundle.mockResolvedValueOnce(false);
154
+ else
155
+ mocks.updateBundle.mockRejectedValueOnce(new Error("download failed"));
156
+ const update = await checkForUpdate({
157
+ client,
158
+ insights: true,
159
+ updateStrategy: "appVersion",
160
+ });
161
+ await update!.updateBundle().catch(() => false);
162
+ expect(sendInsightsEvent).not.toHaveBeenCalled();
163
+ },
164
+ );
165
+
112
166
  it("selects locally and defers Bundle artifact resolution until install", async () => {
113
167
  const { checkForUpdate } = await import("./checkForUpdate");
114
168
  const { client, fetchReleaseCatalog, resolveArtifact } = createClient();
@@ -119,7 +173,7 @@ describe("checkForUpdate Release catalog protocol", () => {
119
173
  });
120
174
 
121
175
  expect(result).toMatchObject({
122
- id: TARGET_BUNDLE_ID,
176
+ id: RELEASE_ID,
123
177
  releaseId: RELEASE_ID,
124
178
  transitionKind: "INSTALL",
125
179
  });
@@ -182,7 +236,7 @@ describe("checkForUpdate Release catalog protocol", () => {
182
236
  },
183
237
  ],
184
238
  });
185
- const { client, resolveArtifact, sendAnalyticsEvent } =
239
+ const { client, resolveArtifact, sendInsightsEvent } =
186
240
  createClient(forceCatalog);
187
241
 
188
242
  const result = await checkForUpdate({
@@ -191,13 +245,14 @@ describe("checkForUpdate Release catalog protocol", () => {
191
245
  });
192
246
 
193
247
  expect(result).toMatchObject({
248
+ id: RELEASE_ID,
194
249
  shouldForceUpdate: false,
195
250
  transitionKind: "ADOPT_RELEASE",
196
251
  });
197
252
  await expect(result?.updateBundle()).resolves.toBe(true);
198
253
  expect(resolveArtifact).not.toHaveBeenCalled();
199
254
  expect(mocks.updateBundle).not.toHaveBeenCalled();
200
- expect(sendAnalyticsEvent).not.toHaveBeenCalled();
255
+ expect(sendInsightsEvent).not.toHaveBeenCalled();
201
256
  expect(mocks.commitReleaseSelection).toHaveBeenCalledWith({
202
257
  guard: expect.objectContaining({ generation: 2, scopeKey: SCOPE_KEY }),
203
258
  selection: expect.objectContaining({
@@ -207,7 +262,7 @@ describe("checkForUpdate Release catalog protocol", () => {
207
262
  });
208
263
  });
209
264
 
210
- it("sends RELEASE_ADOPTED only when analytics is enabled", async () => {
265
+ it("reports same-file selection as UNCHANGED with the selected release identity", async () => {
211
266
  const active: PersistedSelectionReceipt = {
212
267
  catalogId: CATALOG_ID,
213
268
  bundleId: TARGET_BUNDLE_ID,
@@ -227,20 +282,23 @@ describe("checkForUpdate Release catalog protocol", () => {
227
282
  verificationPending: false,
228
283
  });
229
284
  const { checkForUpdate } = await import("./checkForUpdate");
230
- const { client, sendAnalyticsEvent } = createClient();
285
+ const { client, sendInsightsEvent } = createClient();
231
286
 
232
287
  const result = await checkForUpdate({
233
- analytics: true,
288
+ insights: true,
234
289
  client,
235
290
  updateStrategy: "appVersion",
236
291
  });
237
292
  await result?.updateBundle();
238
293
 
239
- expect(sendAnalyticsEvent).toHaveBeenCalledWith(
294
+ expect(sendInsightsEvent).toHaveBeenCalledWith(
240
295
  expect.objectContaining({
296
+ fromBundleId: null,
297
+ updateStrategy: null,
241
298
  fromReleaseId: MINIMUM_RELEASE_ID,
299
+ toBundleId: TARGET_BUNDLE_ID,
242
300
  toReleaseId: RELEASE_ID,
243
- type: "RELEASE_ADOPTED",
301
+ type: "UNCHANGED",
244
302
  }),
245
303
  );
246
304
  });
@@ -280,7 +338,7 @@ describe("checkForUpdate Release catalog protocol", () => {
280
338
  });
281
339
 
282
340
  expect(result).toMatchObject({
283
- id: TARGET_BUNDLE_ID,
341
+ id: RELEASE_ID,
284
342
  releaseId: RELEASE_ID,
285
343
  status: "UPDATE",
286
344
  transitionKind: "INSTALL",
@@ -315,7 +373,7 @@ describe("checkForUpdate Release catalog protocol", () => {
315
373
  });
316
374
 
317
375
  expect(result).toMatchObject({
318
- id: TARGET_BUNDLE_ID,
376
+ id: RELEASE_ID,
319
377
  releaseId: RELEASE_ID,
320
378
  transitionKind: "ADOPT_RELEASE",
321
379
  });
@@ -395,7 +453,7 @@ describe("checkForUpdate Release catalog protocol", () => {
395
453
  });
396
454
 
397
455
  expect(result).toMatchObject({
398
- id: TARGET_BUNDLE_ID,
456
+ id: RELEASE_ID,
399
457
  releaseId: RELEASE_ID,
400
458
  shouldForceUpdate: true,
401
459
  status: "ROLLBACK",
@@ -448,58 +506,70 @@ describe("checkForUpdate Release catalog protocol", () => {
448
506
  });
449
507
 
450
508
  expect(result).toMatchObject({
451
- id: TARGET_BUNDLE_ID,
509
+ id: RELEASE_ID,
452
510
  shouldForceUpdate: true,
453
511
  status: "ROLLBACK",
454
512
  transitionKind: "INSTALL",
455
513
  });
456
514
  });
457
515
 
458
- it("returns a forced built-in rollback only for an active OTA", async () => {
459
- const active: PersistedSelectionReceipt = {
460
- catalogId: CATALOG_ID,
461
- bundleId: CURRENT_BUNDLE_ID,
462
- catalogHash: `sha256:${"b".repeat(64)}`,
463
- channel: CHANNEL,
464
- generation: 1,
465
- kind: "BUNDLE",
466
- releaseId: ACTIVE_RELEASE_ID,
467
- scopeKey: SCOPE_KEY,
468
- selectionContextHash: "old-context",
469
- };
470
- mocks.getActiveUpdateState.mockReturnValueOnce({
471
- activeSelection: active,
472
- highestSeenCatalogs: {},
473
- stableSelection: active,
474
- verificationPending: false,
475
- });
476
- const { checkForUpdate } = await import("./checkForUpdate");
477
- const { client } = createClient(
478
- createCatalog({ releases: [], rollbackReleases: [] }),
479
- );
516
+ it.each(["EMBEDDED", "BUILTIN"] as const)(
517
+ "returns a forced %s rollback with its console ID or built-in fallback",
518
+ async (kind) => {
519
+ const active: PersistedSelectionReceipt = {
520
+ catalogId: CATALOG_ID,
521
+ bundleId: CURRENT_BUNDLE_ID,
522
+ catalogHash: `sha256:${"b".repeat(64)}`,
523
+ channel: CHANNEL,
524
+ generation: 1,
525
+ kind: "BUNDLE",
526
+ releaseId: MINIMUM_RELEASE_ID,
527
+ scopeKey: SCOPE_KEY,
528
+ selectionContextHash: "old-context",
529
+ };
530
+ mocks.getActiveUpdateState.mockReturnValueOnce({
531
+ activeSelection: active,
532
+ highestSeenCatalogs: {},
533
+ stableSelection: active,
534
+ verificationPending: false,
535
+ });
536
+ const { checkForUpdate } = await import("./checkForUpdate");
537
+ const { client, resolveArtifact } = createClient(
538
+ createCatalog({
539
+ releases:
540
+ kind === "EMBEDDED"
541
+ ? [{ ...createCatalog().releases[0]!, kind, bundleId: null }]
542
+ : [],
543
+ rollbackReleases: [],
544
+ }),
545
+ );
480
546
 
481
- const result = await checkForUpdate({
482
- client,
483
- updateStrategy: "appVersion",
484
- });
547
+ const result = await checkForUpdate({
548
+ client,
549
+ updateStrategy: "appVersion",
550
+ });
485
551
 
486
- expect(result).toMatchObject({
487
- id: MINIMUM_RELEASE_ID,
488
- releaseId: null,
489
- shouldForceUpdate: true,
490
- status: "ROLLBACK",
491
- transitionKind: "USE_BUILTIN",
492
- });
493
- await expect(result?.updateBundle()).resolves.toBe(true);
494
- expect(mocks.commitReleaseSelection).toHaveBeenCalledWith(
495
- expect.objectContaining({
496
- selection: expect.objectContaining({
497
- kind: "BUILTIN",
498
- releaseId: null,
552
+ expect(result).toMatchObject({
553
+ id: kind === "EMBEDDED" ? RELEASE_ID : MINIMUM_RELEASE_ID,
554
+ releaseId: kind === "EMBEDDED" ? RELEASE_ID : null,
555
+ shouldForceUpdate: true,
556
+ status: "ROLLBACK",
557
+ transitionKind: kind === "EMBEDDED" ? "USE_EMBEDDED" : "USE_BUILTIN",
558
+ });
559
+ await expect(result?.updateBundle()).resolves.toBe(true);
560
+ expect(mocks.commitReleaseSelection).toHaveBeenCalledWith(
561
+ expect.objectContaining({
562
+ selection: expect.objectContaining({
563
+ bundleId: MINIMUM_RELEASE_ID,
564
+ kind,
565
+ releaseId: kind === "EMBEDDED" ? RELEASE_ID : null,
566
+ }),
499
567
  }),
500
- }),
501
- );
502
- });
568
+ );
569
+ expect(resolveArtifact).not.toHaveBeenCalled();
570
+ expect(mocks.updateBundle).not.toHaveBeenCalled();
571
+ },
572
+ );
503
573
 
504
574
  it("does not surface a rollback when the app already uses built-in bytes", async () => {
505
575
  mocks.getBundleId.mockReturnValueOnce(MINIMUM_RELEASE_ID);
@@ -30,6 +30,7 @@ import {
30
30
  isChannelSwitched,
31
31
  updateBundle,
32
32
  } from "./native";
33
+ import { reportBundleDownloaded } from "./notifyAppReadyInsights";
33
34
  import {
34
35
  hasExpectedReleaseCatalogScope,
35
36
  type ExpectedReleaseCatalogScope,
@@ -83,7 +84,7 @@ export type ReleaseTransitionKind =
83
84
  | "USE_BUILTIN";
84
85
 
85
86
  export interface InternalCheckForUpdateOptions extends CheckForUpdateOptions {
86
- analytics?: boolean;
87
+ insights?: boolean;
87
88
  client: HotUpdaterHttpClient;
88
89
  }
89
90
 
@@ -128,7 +129,7 @@ const resetProgress = () => {
128
129
  });
129
130
  };
130
131
 
131
- const notifyReleaseAdoption = async (input: {
132
+ const notifyUnchangedSelection = async (input: {
132
133
  readonly active: PersistedSelectionReceipt | null;
133
134
  readonly desired: PersistedSelectionReceipt;
134
135
  readonly appVersion: string;
@@ -138,16 +139,15 @@ const notifyReleaseAdoption = async (input: {
138
139
  readonly session: HotUpdaterHttpSession;
139
140
  readonly requestHeaders?: Record<string, string>;
140
141
  readonly requestTimeout?: number;
141
- readonly updateStrategy: "appVersion" | "fingerprint";
142
142
  }): Promise<void> => {
143
143
  const { userId, username } = getPersistedUserIdentity();
144
144
  try {
145
- await input.session.sendAnalyticsEvent({
145
+ await input.session.sendInsightsEvent({
146
146
  appVersion: input.appVersion,
147
147
  channel: input.desired.channel,
148
148
  cohort: input.cohort,
149
149
  fingerprintHash: input.fingerprintHash,
150
- fromBundleId: input.desired.bundleId,
150
+ fromBundleId: null,
151
151
  fromReleaseId: input.active?.releaseId ?? null,
152
152
  installId: getInstallId(),
153
153
  platform: input.platform,
@@ -155,13 +155,13 @@ const notifyReleaseAdoption = async (input: {
155
155
  requestTimeout: input.requestTimeout,
156
156
  toBundleId: input.desired.bundleId,
157
157
  toReleaseId: input.desired.releaseId,
158
- type: "RELEASE_ADOPTED",
159
- updateStrategy: input.updateStrategy,
158
+ type: "UNCHANGED",
159
+ updateStrategy: null,
160
160
  ...(userId === undefined ? {} : { userId }),
161
161
  ...(username === undefined ? {} : { username }),
162
162
  });
163
163
  } catch (error) {
164
- console.warn("[HotUpdater] Release adoption analytics failed:", error);
164
+ console.warn("[HotUpdater] Unchanged selection insights failed:", error);
165
165
  }
166
166
  };
167
167
 
@@ -218,7 +218,8 @@ async function checkForReleaseCatalogUpdate(input: {
218
218
  const scopeKey = catalog.scopeKey;
219
219
 
220
220
  const crashedBundleIds = getCrashHistory();
221
- const active = getActiveUpdateState().activeSelection;
221
+ const activeState = getActiveUpdateState();
222
+ const active = activeState.activeSelection;
222
223
  const explicitScopeSwitch =
223
224
  input.explicitChannel !== undefined &&
224
225
  input.explicitChannel !== input.currentChannel;
@@ -340,12 +341,8 @@ async function checkForReleaseCatalogUpdate(input: {
340
341
  guard,
341
342
  selection: receipt,
342
343
  });
343
- if (
344
- committed &&
345
- transitionKind === "ADOPT_RELEASE" &&
346
- options.analytics
347
- ) {
348
- await notifyReleaseAdoption({
344
+ if (committed && transitionKind === "ADOPT_RELEASE" && options.insights) {
345
+ await notifyUnchangedSelection({
349
346
  active,
350
347
  appVersion: input.currentAppVersion,
351
348
  cohort: input.cohort,
@@ -355,7 +352,6 @@ async function checkForReleaseCatalogUpdate(input: {
355
352
  requestHeaders: options.requestHeaders,
356
353
  requestTimeout: options.requestTimeout,
357
354
  session,
358
- updateStrategy: options.updateStrategy,
359
355
  });
360
356
  }
361
357
  return committed;
@@ -370,7 +366,7 @@ async function checkForReleaseCatalogUpdate(input: {
370
366
  if (!isReleaseSelectionCurrent(guard)) {
371
367
  throw new StaleReleaseCatalogError();
372
368
  }
373
- return updateBundle({
369
+ const downloaded = await updateBundle({
374
370
  bundleId: desired.bundleId,
375
371
  changedAssets: artifact.changedAssets ?? null,
376
372
  channel: input.targetChannel,
@@ -382,12 +378,28 @@ async function checkForReleaseCatalogUpdate(input: {
382
378
  shouldSkipCurrentBundleIdCheck: true,
383
379
  status: desired.status,
384
380
  });
381
+ if (downloaded) {
382
+ await reportBundleDownloaded(options, {
383
+ fromBundleId: input.currentBundleId,
384
+ fromReleaseId:
385
+ active?.bundleId === input.currentBundleId
386
+ ? active.releaseId
387
+ : activeState.stableSelection?.bundleId === input.currentBundleId
388
+ ? activeState.stableSelection.releaseId
389
+ : null,
390
+ toBundleId: desired.bundleId,
391
+ toReleaseId: desired.releaseId,
392
+ channel: input.targetChannel,
393
+ updateStrategy: options.updateStrategy,
394
+ });
395
+ }
396
+ return downloaded;
385
397
  };
386
398
 
387
399
  return {
388
400
  fileHash: null,
389
401
  fileUrl: null,
390
- id: desired.bundleId,
402
+ id: desired.releaseId ?? desired.bundleId,
391
403
  message: release?.message ?? null,
392
404
  releaseId: desired.releaseId,
393
405
  rolloutCohortCount: release?.rolloutCohortCount ?? 1000,
package/src/httpClient.ts CHANGED
@@ -27,7 +27,7 @@ export interface ArtifactRequest {
27
27
  readonly requestTimeout?: number;
28
28
  }
29
29
 
30
- interface AnalyticsEventCommonParams {
30
+ interface InsightsEventCommonParams {
31
31
  readonly installId: string;
32
32
  readonly userId?: string;
33
33
  readonly username?: string;
@@ -42,30 +42,30 @@ interface AnalyticsEventCommonParams {
42
42
  readonly requestTimeout?: number;
43
43
  }
44
44
 
45
- type AnalyticsTransitionEventParams = AnalyticsEventCommonParams & {
46
- readonly type: "UPDATE_APPLIED" | "RECOVERED" | "RELEASE_ADOPTED";
45
+ type InsightsTransitionEventParams = InsightsEventCommonParams & {
46
+ readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED";
47
47
  readonly fromBundleId: string;
48
48
  readonly toBundleId: string;
49
49
  readonly updateStrategy: "fingerprint" | "appVersion";
50
50
  };
51
51
 
52
- type AnalyticsUnchangedEventParams = AnalyticsEventCommonParams & {
52
+ type InsightsUnchangedEventParams = InsightsEventCommonParams & {
53
53
  readonly type: "UNCHANGED";
54
54
  readonly fromBundleId: null;
55
55
  readonly toBundleId: string;
56
56
  readonly updateStrategy: null;
57
57
  };
58
58
 
59
- export type AnalyticsEventParams =
60
- | AnalyticsTransitionEventParams
61
- | AnalyticsUnchangedEventParams;
59
+ export type InsightsEventParams =
60
+ | InsightsTransitionEventParams
61
+ | InsightsUnchangedEventParams;
62
62
 
63
63
  export interface HotUpdaterHttpSession {
64
64
  fetchReleaseCatalog: (
65
65
  params: ReleaseCatalogRequest,
66
66
  ) => Promise<ReleaseCatalog>;
67
67
  resolveArtifact: (params: ArtifactRequest) => Promise<ArtifactInfo>;
68
- sendAnalyticsEvent: (params: AnalyticsEventParams) => Promise<void>;
68
+ sendInsightsEvent: (params: InsightsEventParams) => Promise<void>;
69
69
  }
70
70
 
71
71
  export interface HotUpdaterHttpClient {
@@ -147,9 +147,9 @@ const resolveArtifactUrls = (
147
147
  }),
148
148
  });
149
149
 
150
- const sendAnalyticsEvent = async (
150
+ const sendInsightsEvent = async (
151
151
  baseURL: string,
152
- params: AnalyticsEventParams,
152
+ params: InsightsEventParams,
153
153
  ): Promise<void> => {
154
154
  const controller = new AbortController();
155
155
  const timeoutId = setTimeout(() => {
@@ -250,7 +250,7 @@ const createSession = (baseURL: string): HotUpdaterHttpSession => ({
250
250
  });
251
251
  return resolveArtifactUrls(baseURL, info);
252
252
  },
253
- sendAnalyticsEvent: (params) => sendAnalyticsEvent(baseURL, params),
253
+ sendInsightsEvent: (params) => sendInsightsEvent(baseURL, params),
254
254
  });
255
255
 
256
256
  /** Creates the private HTTP client used by HotUpdater.init and HotUpdater.wrap. */