@hot-updater/plugin-insights 1.0.0-rc.32 → 1.0.0-rc.34

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.
@@ -112,8 +112,7 @@ const insights = (options = {}) => {
112
112
  fromReleaseId: result.fromReleaseId,
113
113
  toBundleId: result.toBundleId,
114
114
  toReleaseId: result.toReleaseId,
115
- updateStrategy: result.updateStrategy,
116
- ...result.status === "RECOVERED" && result.previousProcessExit !== null ? { metadata: { previousProcessExit: result.previousProcessExit } } : {}
115
+ updateStrategy: result.updateStrategy
117
116
  }));
118
117
  };
119
118
  const onUpdateCheck = (result) => {
@@ -168,8 +167,7 @@ const insights = (options = {}) => {
168
167
  ...error.resource === void 0 ? {} : { resource: error.resource },
169
168
  ...error.httpStatus === void 0 ? {} : { httpStatus: error.httpStatus },
170
169
  ...error.transport === void 0 ? {} : { transport: error.transport },
171
- ...error.originCode === void 0 ? {} : { originCode: error.originCode },
172
- ...error.previousProcessExit === void 0 ? {} : { previousProcessExit: error.previousProcessExit }
170
+ ...error.originCode === void 0 ? {} : { originCode: error.originCode }
173
171
  } }
174
172
  }, (now, installId) => require_eventId.createKeyedUUIDv7([
175
173
  installId,
@@ -111,8 +111,7 @@ const insights = (options = {}) => {
111
111
  fromReleaseId: result.fromReleaseId,
112
112
  toBundleId: result.toBundleId,
113
113
  toReleaseId: result.toReleaseId,
114
- updateStrategy: result.updateStrategy,
115
- ...result.status === "RECOVERED" && result.previousProcessExit !== null ? { metadata: { previousProcessExit: result.previousProcessExit } } : {}
114
+ updateStrategy: result.updateStrategy
116
115
  }));
117
116
  };
118
117
  const onUpdateCheck = (result) => {
@@ -167,8 +166,7 @@ const insights = (options = {}) => {
167
166
  ...error.resource === void 0 ? {} : { resource: error.resource },
168
167
  ...error.httpStatus === void 0 ? {} : { httpStatus: error.httpStatus },
169
168
  ...error.transport === void 0 ? {} : { transport: error.transport },
170
- ...error.originCode === void 0 ? {} : { originCode: error.originCode },
171
- ...error.previousProcessExit === void 0 ? {} : { previousProcessExit: error.previousProcessExit }
169
+ ...error.originCode === void 0 ? {} : { originCode: error.originCode }
172
170
  } }
173
171
  }, (now, installId) => createKeyedUUIDv7([
174
172
  installId,
@@ -166,7 +166,7 @@ const createValidatedInsightsModel = (model) => ({
166
166
  async getReleaseActivity(input) {
167
167
  if (!require_eventRow.isRecord(input) || !hasOnlyKeys(input, ["releases"]) || !Array.isArray(input.releases) || input.releases.length < 1 || input.releases.length > 100 || !input.releases.every(isReleaseReference)) invalidQuery();
168
168
  const result = await model.getReleaseActivity(input);
169
- if (!require_eventRow.isRecord(result) || !isTimestamp(result.measuredAtMs) || !Array.isArray(result.data) || result.data.some((item) => !require_eventRow.isRecord(item) || !isReleaseReference(item.release) || !require_eventRow.isRecord(item.metrics) || !isTimestamp(item.metrics.downloads) || !isTimestamp(item.metrics.launches) || !isTimestamp(item.metrics.failedLaunches))) invalidResult();
169
+ if (!require_eventRow.isRecord(result) || !isTimestamp(result.measuredAtMs) || !Array.isArray(result.data) || result.data.some((item) => !require_eventRow.isRecord(item) || !isReleaseReference(item.release) || !require_eventRow.isRecord(item.metrics) || !isTimestamp(item.metrics.downloads) || !isTimestamp(item.metrics.applies) || !isTimestamp(item.metrics.failedLaunches))) invalidResult();
170
170
  return result;
171
171
  },
172
172
  async getAppUsage(input) {
@@ -166,7 +166,7 @@ const createValidatedInsightsModel = (model) => ({
166
166
  async getReleaseActivity(input) {
167
167
  if (!isRecord(input) || !hasOnlyKeys(input, ["releases"]) || !Array.isArray(input.releases) || input.releases.length < 1 || input.releases.length > 100 || !input.releases.every(isReleaseReference)) invalidQuery();
168
168
  const result = await model.getReleaseActivity(input);
169
- if (!isRecord(result) || !isTimestamp(result.measuredAtMs) || !Array.isArray(result.data) || result.data.some((item) => !isRecord(item) || !isReleaseReference(item.release) || !isRecord(item.metrics) || !isTimestamp(item.metrics.downloads) || !isTimestamp(item.metrics.launches) || !isTimestamp(item.metrics.failedLaunches))) invalidResult();
169
+ if (!isRecord(result) || !isTimestamp(result.measuredAtMs) || !Array.isArray(result.data) || result.data.some((item) => !isRecord(item) || !isReleaseReference(item.release) || !isRecord(item.metrics) || !isTimestamp(item.metrics.downloads) || !isTimestamp(item.metrics.applies) || !isTimestamp(item.metrics.failedLaunches))) invalidResult();
170
170
  return result;
171
171
  },
172
172
  async getAppUsage(input) {
@@ -18,8 +18,6 @@ type BundleEventFailureInput = {
18
18
  /** Original client error text, bounded to fit the event payload. */
19
19
  readonly errorMessage?: string;
20
20
  readonly errorStack?: string;
21
- /** Android's `ApplicationExitInfo` reason for the process before this one. */
22
- readonly previousProcessExit?: string;
23
21
  };
24
22
  /**
25
23
  * The body of `POST /events`. Fields the server does not know are ignored, so
@@ -62,13 +60,7 @@ type CreateBundleEventRequest = (Movement & {
62
60
  readonly patchFallback?: true;
63
61
  };
64
62
  }) | (Movement & {
65
- readonly type: "UPDATE_APPLIED";
66
- }) | (Movement & {
67
- readonly type: "RECOVERED";
68
- readonly metadata?: {
69
- /** Android's `ApplicationExitInfo` reason for the crashed process. */
70
- readonly previousProcessExit?: string;
71
- };
63
+ readonly type: "UPDATE_APPLIED" | "RECOVERED";
72
64
  }) | (Movement & {
73
65
  /**
74
66
  * An update check, download, or install that failed: `fromBundleId`
@@ -105,8 +97,6 @@ type EventHistoryRow = {
105
97
  readonly delivery?: NonNullable<DatabaseBundleEventMetadata["delivery"]>;
106
98
  /** `UPDATE_DOWNLOADED`: a patch failed, and the files or the archive came instead. */
107
99
  readonly patchFallback?: true;
108
- /** `RECOVERED`: Android's reason the crashed process exited. */
109
- readonly previousProcessExit?: string;
110
100
  };
111
101
  type InstallationHistoryRow = EventHistoryRow & {
112
102
  readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED" | "UPDATE_FAILED";
@@ -18,8 +18,6 @@ type BundleEventFailureInput = {
18
18
  /** Original client error text, bounded to fit the event payload. */
19
19
  readonly errorMessage?: string;
20
20
  readonly errorStack?: string;
21
- /** Android's `ApplicationExitInfo` reason for the process before this one. */
22
- readonly previousProcessExit?: string;
23
21
  };
24
22
  /**
25
23
  * The body of `POST /events`. Fields the server does not know are ignored, so
@@ -62,13 +60,7 @@ type CreateBundleEventRequest = (Movement & {
62
60
  readonly patchFallback?: true;
63
61
  };
64
62
  }) | (Movement & {
65
- readonly type: "UPDATE_APPLIED";
66
- }) | (Movement & {
67
- readonly type: "RECOVERED";
68
- readonly metadata?: {
69
- /** Android's `ApplicationExitInfo` reason for the crashed process. */
70
- readonly previousProcessExit?: string;
71
- };
63
+ readonly type: "UPDATE_APPLIED" | "RECOVERED";
72
64
  }) | (Movement & {
73
65
  /**
74
66
  * An update check, download, or install that failed: `fromBundleId`
@@ -105,8 +97,6 @@ type EventHistoryRow = {
105
97
  readonly delivery?: NonNullable<DatabaseBundleEventMetadata["delivery"]>;
106
98
  /** `UPDATE_DOWNLOADED`: a patch failed, and the files or the archive came instead. */
107
99
  readonly patchFallback?: true;
108
- /** `RECOVERED`: Android's reason the crashed process exited. */
109
- readonly previousProcessExit?: string;
110
100
  };
111
101
  type InstallationHistoryRow = EventHistoryRow & {
112
102
  readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED" | "UPDATE_FAILED";
@@ -69,7 +69,7 @@ const DELIVERIES = [
69
69
  "manifest",
70
70
  "archive"
71
71
  ];
72
- /** A storage error code or an Android exit reason: letters, digits, and `._-`. */
72
+ /** A storage error code: letters, digits, and `._-`. */
73
73
  const CODE = /^[A-Za-z0-9._-]{1,64}$/;
74
74
  const readCode = (value) => typeof value === "string" && CODE.test(value) ? value : void 0;
75
75
  const readMetadata = (payload) => isRecord(payload.metadata) ? payload.metadata : {};
@@ -85,7 +85,6 @@ function readFailure(value) {
85
85
  const originCode = readCode(failure.originCode);
86
86
  const errorMessage = typeof failure.errorMessage === "string" && failure.errorMessage.length <= 2048 ? failure.errorMessage : void 0;
87
87
  const errorStack = typeof failure.errorStack === "string" && failure.errorStack.length <= 4096 ? failure.errorStack : void 0;
88
- const previousProcessExit = readCode(failure.previousProcessExit);
89
88
  return {
90
89
  stage: oneOf(STAGES, failure.stage),
91
90
  reason: oneOf(REASONS, failure.reason),
@@ -94,8 +93,7 @@ function readFailure(value) {
94
93
  ...failure.transport == null ? {} : { transport: oneOf(TRANSPORTS, failure.transport) },
95
94
  ...originCode === void 0 ? {} : { originCode },
96
95
  ...errorMessage === void 0 ? {} : { errorMessage },
97
- ...errorStack === void 0 ? {} : { errorStack },
98
- ...previousProcessExit === void 0 ? {} : { previousProcessExit }
96
+ ...errorStack === void 0 ? {} : { errorStack }
99
97
  };
100
98
  }
101
99
  function readHttpResponse(value) {
@@ -185,21 +183,11 @@ function requireEvent(payload) {
185
183
  ...Object.keys(read).length === 0 ? {} : { metadata: read }
186
184
  };
187
185
  }
188
- case "UPDATE_APPLIED": return {
186
+ case "UPDATE_APPLIED":
187
+ case "RECOVERED": return {
189
188
  ...movement(),
190
189
  type
191
190
  };
192
- case "RECOVERED": {
193
- const previousProcessExit = readCode(metadata.previousProcessExit);
194
- return {
195
- ...movement(),
196
- type,
197
- ...previousProcessExit === void 0 ? {} : { metadata: {
198
- ...httpMetadata,
199
- previousProcessExit
200
- } }
201
- };
202
- }
203
191
  case "UPDATE_FAILED": return {
204
192
  ...movement(),
205
193
  type,
@@ -265,24 +253,13 @@ function createBundleEventRow(input) {
265
253
  }
266
254
  };
267
255
  }
268
- case "UPDATE_APPLIED": return {
256
+ case "UPDATE_APPLIED":
257
+ case "RECOVERED": return {
269
258
  ...base,
270
259
  from_bundle_id: input.fromBundleId,
271
260
  type: input.type,
272
261
  metadata
273
262
  };
274
- case "RECOVERED": {
275
- const exit = input.metadata?.previousProcessExit;
276
- return {
277
- ...base,
278
- from_bundle_id: input.fromBundleId,
279
- type: input.type,
280
- metadata: {
281
- ...metadata,
282
- ...exit === void 0 ? {} : { previous_process_exit: exit }
283
- }
284
- };
285
- }
286
263
  case "UPDATE_FAILED": {
287
264
  const { failure } = input.metadata;
288
265
  return {
@@ -299,8 +276,7 @@ function createBundleEventRow(input) {
299
276
  ...failure.resource === void 0 ? {} : { resource: failure.resource },
300
277
  ...failure.httpStatus === void 0 ? {} : { http_status: failure.httpStatus },
301
278
  ...failure.transport === void 0 ? {} : { transport: failure.transport },
302
- ...failure.originCode === void 0 ? {} : { origin_code: failure.originCode },
303
- ...failure.previousProcessExit === void 0 ? {} : { previous_process_exit: failure.previousProcessExit }
279
+ ...failure.originCode === void 0 ? {} : { origin_code: failure.originCode }
304
280
  }
305
281
  }
306
282
  };
@@ -69,7 +69,7 @@ const DELIVERIES = [
69
69
  "manifest",
70
70
  "archive"
71
71
  ];
72
- /** A storage error code or an Android exit reason: letters, digits, and `._-`. */
72
+ /** A storage error code: letters, digits, and `._-`. */
73
73
  const CODE = /^[A-Za-z0-9._-]{1,64}$/;
74
74
  const readCode = (value) => typeof value === "string" && CODE.test(value) ? value : void 0;
75
75
  const readMetadata = (payload) => isRecord(payload.metadata) ? payload.metadata : {};
@@ -85,7 +85,6 @@ function readFailure(value) {
85
85
  const originCode = readCode(failure.originCode);
86
86
  const errorMessage = typeof failure.errorMessage === "string" && failure.errorMessage.length <= 2048 ? failure.errorMessage : void 0;
87
87
  const errorStack = typeof failure.errorStack === "string" && failure.errorStack.length <= 4096 ? failure.errorStack : void 0;
88
- const previousProcessExit = readCode(failure.previousProcessExit);
89
88
  return {
90
89
  stage: oneOf(STAGES, failure.stage),
91
90
  reason: oneOf(REASONS, failure.reason),
@@ -94,8 +93,7 @@ function readFailure(value) {
94
93
  ...failure.transport == null ? {} : { transport: oneOf(TRANSPORTS, failure.transport) },
95
94
  ...originCode === void 0 ? {} : { originCode },
96
95
  ...errorMessage === void 0 ? {} : { errorMessage },
97
- ...errorStack === void 0 ? {} : { errorStack },
98
- ...previousProcessExit === void 0 ? {} : { previousProcessExit }
96
+ ...errorStack === void 0 ? {} : { errorStack }
99
97
  };
100
98
  }
101
99
  function readHttpResponse(value) {
@@ -185,21 +183,11 @@ function requireEvent(payload) {
185
183
  ...Object.keys(read).length === 0 ? {} : { metadata: read }
186
184
  };
187
185
  }
188
- case "UPDATE_APPLIED": return {
186
+ case "UPDATE_APPLIED":
187
+ case "RECOVERED": return {
189
188
  ...movement(),
190
189
  type
191
190
  };
192
- case "RECOVERED": {
193
- const previousProcessExit = readCode(metadata.previousProcessExit);
194
- return {
195
- ...movement(),
196
- type,
197
- ...previousProcessExit === void 0 ? {} : { metadata: {
198
- ...httpMetadata,
199
- previousProcessExit
200
- } }
201
- };
202
- }
203
191
  case "UPDATE_FAILED": return {
204
192
  ...movement(),
205
193
  type,
@@ -265,24 +253,13 @@ function createBundleEventRow(input) {
265
253
  }
266
254
  };
267
255
  }
268
- case "UPDATE_APPLIED": return {
256
+ case "UPDATE_APPLIED":
257
+ case "RECOVERED": return {
269
258
  ...base,
270
259
  from_bundle_id: input.fromBundleId,
271
260
  type: input.type,
272
261
  metadata
273
262
  };
274
- case "RECOVERED": {
275
- const exit = input.metadata?.previousProcessExit;
276
- return {
277
- ...base,
278
- from_bundle_id: input.fromBundleId,
279
- type: input.type,
280
- metadata: {
281
- ...metadata,
282
- ...exit === void 0 ? {} : { previous_process_exit: exit }
283
- }
284
- };
285
- }
286
263
  case "UPDATE_FAILED": {
287
264
  const { failure } = input.metadata;
288
265
  return {
@@ -299,8 +276,7 @@ function createBundleEventRow(input) {
299
276
  ...failure.resource === void 0 ? {} : { resource: failure.resource },
300
277
  ...failure.httpStatus === void 0 ? {} : { http_status: failure.httpStatus },
301
278
  ...failure.transport === void 0 ? {} : { transport: failure.transport },
302
- ...failure.originCode === void 0 ? {} : { origin_code: failure.originCode },
303
- ...failure.previousProcessExit === void 0 ? {} : { previous_process_exit: failure.previousProcessExit }
279
+ ...failure.originCode === void 0 ? {} : { origin_code: failure.originCode }
304
280
  }
305
281
  }
306
282
  };
@@ -4,8 +4,8 @@ const isOptional = (value, key, valid) => !Object.hasOwn(value, key) || valid(va
4
4
  const isString = (value) => typeof value === "string";
5
5
  const isDatabaseHttpResponse = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && (value.resource === "catalog" || value.resource === "artifact") && isString(value.path) && Number.isSafeInteger(value.status) && (value.body === null || isString(value.body)) && typeof value.body_truncated === "boolean" && Number.isSafeInteger(value.received_at_ms);
6
6
  /** An `UPDATE_FAILED` report's stored failure: a stage and a reason, and what else the client knew. */
7
- const isDatabaseBundleEventFailure = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && isString(value.stage) && isString(value.reason) && isOptional(value, "resource", isString) && isOptional(value, "http_status", (status) => Number.isSafeInteger(status)) && isOptional(value, "transport", isString) && isOptional(value, "origin_code", isString) && isOptional(value, "error_message", isString) && isOptional(value, "error_stack", isString) && isOptional(value, "previous_process_exit", isString);
8
- const isDatabaseBundleEventMetadata = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "http_response", isDatabaseHttpResponse) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean") && isOptional(value, "previous_process_exit", isString);
7
+ const isDatabaseBundleEventFailure = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && isString(value.stage) && isString(value.reason) && isOptional(value, "resource", isString) && isOptional(value, "http_status", (status) => Number.isSafeInteger(status)) && isOptional(value, "transport", isString) && isOptional(value, "origin_code", isString) && isOptional(value, "error_message", isString) && isOptional(value, "error_stack", isString);
8
+ const isDatabaseBundleEventMetadata = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "http_response", isDatabaseHttpResponse) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean");
9
9
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
10
10
  const isIdentity = (value) => typeof value === "string" && value.length > 0 && value.length <= 255;
11
11
  const isTextOrNull = (value) => value === null || typeof value === "string";
@@ -16,8 +16,6 @@ type BundleEventFailure = DatabaseJsonObject & {
16
16
  readonly origin_code?: string;
17
17
  readonly error_message?: string;
18
18
  readonly error_stack?: string;
19
- /** Android's `ApplicationExitInfo` reason for the process before this one. */
20
- readonly previous_process_exit?: string;
21
19
  };
22
20
  type DatabaseHttpResponse = DatabaseJsonObject & {
23
21
  readonly resource: "catalog" | "artifact";
@@ -40,8 +38,6 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
40
38
  readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
41
39
  /** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
42
40
  readonly patch_fallback?: boolean;
43
- /** `RECOVERED`: Android's `ApplicationExitInfo` reason for the crashed process. */
44
- readonly previous_process_exit?: string;
45
41
  };
46
42
  type BundleEventRowBase = {
47
43
  readonly id: string;
@@ -16,8 +16,6 @@ type BundleEventFailure = DatabaseJsonObject & {
16
16
  readonly origin_code?: string;
17
17
  readonly error_message?: string;
18
18
  readonly error_stack?: string;
19
- /** Android's `ApplicationExitInfo` reason for the process before this one. */
20
- readonly previous_process_exit?: string;
21
19
  };
22
20
  type DatabaseHttpResponse = DatabaseJsonObject & {
23
21
  readonly resource: "catalog" | "artifact";
@@ -40,8 +38,6 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
40
38
  readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
41
39
  /** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
42
40
  readonly patch_fallback?: boolean;
43
- /** `RECOVERED`: Android's `ApplicationExitInfo` reason for the crashed process. */
44
- readonly previous_process_exit?: string;
45
41
  };
46
42
  type BundleEventRowBase = {
47
43
  readonly id: string;
@@ -4,8 +4,8 @@ const isOptional = (value, key, valid) => !Object.hasOwn(value, key) || valid(va
4
4
  const isString = (value) => typeof value === "string";
5
5
  const isDatabaseHttpResponse = (value) => isDatabaseJsonObject(value) && (value.resource === "catalog" || value.resource === "artifact") && isString(value.path) && Number.isSafeInteger(value.status) && (value.body === null || isString(value.body)) && typeof value.body_truncated === "boolean" && Number.isSafeInteger(value.received_at_ms);
6
6
  /** An `UPDATE_FAILED` report's stored failure: a stage and a reason, and what else the client knew. */
7
- const isDatabaseBundleEventFailure = (value) => isDatabaseJsonObject(value) && isString(value.stage) && isString(value.reason) && isOptional(value, "resource", isString) && isOptional(value, "http_status", (status) => Number.isSafeInteger(status)) && isOptional(value, "transport", isString) && isOptional(value, "origin_code", isString) && isOptional(value, "error_message", isString) && isOptional(value, "error_stack", isString) && isOptional(value, "previous_process_exit", isString);
8
- const isDatabaseBundleEventMetadata = (value) => isDatabaseJsonObject(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "http_response", isDatabaseHttpResponse) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean") && isOptional(value, "previous_process_exit", isString);
7
+ const isDatabaseBundleEventFailure = (value) => isDatabaseJsonObject(value) && isString(value.stage) && isString(value.reason) && isOptional(value, "resource", isString) && isOptional(value, "http_status", (status) => Number.isSafeInteger(status)) && isOptional(value, "transport", isString) && isOptional(value, "origin_code", isString) && isOptional(value, "error_message", isString) && isOptional(value, "error_stack", isString);
8
+ const isDatabaseBundleEventMetadata = (value) => isDatabaseJsonObject(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "http_response", isDatabaseHttpResponse) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean");
9
9
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
10
10
  const isIdentity = (value) => typeof value === "string" && value.length > 0 && value.length <= 255;
11
11
  const isTextOrNull = (value) => value === null || typeof value === "string";
@@ -88,7 +88,7 @@ const insights = (options = {}) => {
88
88
  const plugin = (0, _hot_updater_plugin_core.definePlugin)({
89
89
  id: "insights",
90
90
  namespace: false,
91
- schemaVersion: "1.2.0",
91
+ schemaVersion: "1.0.0",
92
92
  schema: require_schema.createInsightsSchema(retention),
93
93
  init: ({ db, now }) => {
94
94
  const api = createInsightsApi(db, now, retention);
@@ -180,7 +180,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
180
180
  readonly bucket_start_ms: {
181
181
  readonly type: "integer";
182
182
  };
183
- }, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
183
+ }, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
184
184
  readonly window: {
185
185
  readonly eq: readonly ["identity"];
186
186
  readonly sort: readonly ["bucket_start_ms"];
@@ -208,7 +208,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
208
208
  readonly bucket_start_ms: {
209
209
  readonly type: "integer";
210
210
  };
211
- }, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
211
+ }, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
212
212
  readonly window: {
213
213
  readonly eq: readonly ["identity"];
214
214
  readonly sort: readonly ["bucket_start_ms"];
@@ -236,7 +236,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
236
236
  readonly bucket_start_ms: {
237
237
  readonly type: "integer";
238
238
  };
239
- }, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
239
+ }, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks" | "applies" | "failed_updates", {
240
240
  readonly window: {
241
241
  readonly eq: readonly ["identity"];
242
242
  readonly sort: readonly ["bucket_start_ms"];
@@ -180,7 +180,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
180
180
  readonly bucket_start_ms: {
181
181
  readonly type: "integer";
182
182
  };
183
- }, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
183
+ }, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
184
184
  readonly window: {
185
185
  readonly eq: readonly ["identity"];
186
186
  readonly sort: readonly ["bucket_start_ms"];
@@ -208,7 +208,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
208
208
  readonly bucket_start_ms: {
209
209
  readonly type: "integer";
210
210
  };
211
- }, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
211
+ }, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
212
212
  readonly window: {
213
213
  readonly eq: readonly ["identity"];
214
214
  readonly sort: readonly ["bucket_start_ms"];
@@ -236,7 +236,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
236
236
  readonly bucket_start_ms: {
237
237
  readonly type: "integer";
238
238
  };
239
- }, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
239
+ }, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks" | "applies" | "failed_updates", {
240
240
  readonly window: {
241
241
  readonly eq: readonly ["identity"];
242
242
  readonly sort: readonly ["bucket_start_ms"];
@@ -87,7 +87,7 @@ const insights = (options = {}) => {
87
87
  const plugin = definePlugin({
88
88
  id: "insights",
89
89
  namespace: false,
90
- schemaVersion: "1.2.0",
90
+ schemaVersion: "1.0.0",
91
91
  schema: createInsightsSchema(retention),
92
92
  init: ({ db, now }) => {
93
93
  const api = createInsightsApi(db, now, retention);
@@ -95,8 +95,11 @@ type InsightsCoverage = {
95
95
  * which are kept.
96
96
  */
97
97
  interface ReleaseActivityMetrics {
98
+ /** Download reports of the release. */
98
99
  readonly downloads: number;
99
- readonly launches: number;
100
+ /** Apply reports of the release: installations that started running it. */
101
+ readonly applies: number;
102
+ /** Launches that crashed on the release and recovered to the one before. */
100
103
  readonly failedLaunches: number;
101
104
  }
102
105
  interface InsightsGetReleaseActivityInput {
@@ -95,8 +95,11 @@ type InsightsCoverage = {
95
95
  * which are kept.
96
96
  */
97
97
  interface ReleaseActivityMetrics {
98
+ /** Download reports of the release. */
98
99
  readonly downloads: number;
99
- readonly launches: number;
100
+ /** Apply reports of the release: installations that started running it. */
101
+ readonly applies: number;
102
+ /** Launches that crashed on the release and recovered to the one before. */
100
103
  readonly failedLaunches: number;
101
104
  }
102
105
  interface InsightsGetReleaseActivityInput {
@@ -31,7 +31,7 @@ const insightsOverviewDeltas = (event) => {
31
31
  counters.set(key, {
32
32
  identity,
33
33
  downloads: (previous?.downloads ?? 0) + values.downloads,
34
- launches: (previous?.launches ?? 0) + values.launches,
34
+ applies: (previous?.applies ?? 0) + values.applies,
35
35
  failedLaunches: (previous?.failedLaunches ?? 0) + values.failedLaunches,
36
36
  activityIdentity: previous?.activityIdentity ?? values.activityIdentity
37
37
  });
@@ -39,7 +39,7 @@ const insightsOverviewDeltas = (event) => {
39
39
  const metric = (releaseId, values) => {
40
40
  const windowed = {
41
41
  ...values,
42
- launches: 0
42
+ applies: 0
43
43
  };
44
44
  if (releaseId !== null) for (const [periodKind, start] of [["lifetime", 0], ["hour", bucketStartMs]]) append({
45
45
  scopeKind: "release",
@@ -66,21 +66,19 @@ const insightsOverviewDeltas = (event) => {
66
66
  };
67
67
  if (event.type === "UPDATE_DOWNLOADED") metric(event.to_release_id, {
68
68
  downloads: 1,
69
- launches: 0,
69
+ applies: 0,
70
70
  failedLaunches: 0
71
71
  });
72
- else if (event.type !== "UPDATE_FAILED") {
73
- metric(event.to_release_id, {
74
- downloads: 0,
75
- launches: 1,
76
- failedLaunches: 0
77
- });
78
- if (event.type === "RECOVERED") metric(event.from_release_id, {
79
- downloads: 0,
80
- launches: 0,
81
- failedLaunches: 1
82
- });
83
- }
72
+ else if (event.type === "UPDATE_APPLIED") metric(event.to_release_id, {
73
+ downloads: 0,
74
+ applies: 1,
75
+ failedLaunches: 0
76
+ });
77
+ else if (event.type === "RECOVERED") metric(event.from_release_id, {
78
+ downloads: 0,
79
+ applies: 0,
80
+ failedLaunches: 1
81
+ });
84
82
  for (const platform of [event.platform, "all"]) for (const appVersionKind of ["specific", "all"]) append({
85
83
  scopeKind: "usage",
86
84
  releaseKind: "all",
@@ -93,7 +91,7 @@ const insightsOverviewDeltas = (event) => {
93
91
  bucketStartMs
94
92
  }, {
95
93
  downloads: 0,
96
- launches: 0,
94
+ applies: 0,
97
95
  failedLaunches: 0,
98
96
  activityIdentity: event.install_id
99
97
  });
@@ -31,7 +31,7 @@ const insightsOverviewDeltas = (event) => {
31
31
  counters.set(key, {
32
32
  identity,
33
33
  downloads: (previous?.downloads ?? 0) + values.downloads,
34
- launches: (previous?.launches ?? 0) + values.launches,
34
+ applies: (previous?.applies ?? 0) + values.applies,
35
35
  failedLaunches: (previous?.failedLaunches ?? 0) + values.failedLaunches,
36
36
  activityIdentity: previous?.activityIdentity ?? values.activityIdentity
37
37
  });
@@ -39,7 +39,7 @@ const insightsOverviewDeltas = (event) => {
39
39
  const metric = (releaseId, values) => {
40
40
  const windowed = {
41
41
  ...values,
42
- launches: 0
42
+ applies: 0
43
43
  };
44
44
  if (releaseId !== null) for (const [periodKind, start] of [["lifetime", 0], ["hour", bucketStartMs]]) append({
45
45
  scopeKind: "release",
@@ -66,21 +66,19 @@ const insightsOverviewDeltas = (event) => {
66
66
  };
67
67
  if (event.type === "UPDATE_DOWNLOADED") metric(event.to_release_id, {
68
68
  downloads: 1,
69
- launches: 0,
69
+ applies: 0,
70
70
  failedLaunches: 0
71
71
  });
72
- else if (event.type !== "UPDATE_FAILED") {
73
- metric(event.to_release_id, {
74
- downloads: 0,
75
- launches: 1,
76
- failedLaunches: 0
77
- });
78
- if (event.type === "RECOVERED") metric(event.from_release_id, {
79
- downloads: 0,
80
- launches: 0,
81
- failedLaunches: 1
82
- });
83
- }
72
+ else if (event.type === "UPDATE_APPLIED") metric(event.to_release_id, {
73
+ downloads: 0,
74
+ applies: 1,
75
+ failedLaunches: 0
76
+ });
77
+ else if (event.type === "RECOVERED") metric(event.from_release_id, {
78
+ downloads: 0,
79
+ applies: 0,
80
+ failedLaunches: 1
81
+ });
84
82
  for (const platform of [event.platform, "all"]) for (const appVersionKind of ["specific", "all"]) append({
85
83
  scopeKind: "usage",
86
84
  releaseKind: "all",
@@ -93,7 +91,7 @@ const insightsOverviewDeltas = (event) => {
93
91
  bucketStartMs
94
92
  }, {
95
93
  downloads: 0,
96
- launches: 0,
94
+ applies: 0,
97
95
  failedLaunches: 0,
98
96
  activityIdentity: event.install_id
99
97
  });
@@ -152,10 +152,9 @@ const toFailure = (failure) => ({
152
152
  ...failure.resource === void 0 ? {} : { resource: failure.resource },
153
153
  ...failure.http_status === void 0 ? {} : { httpStatus: failure.http_status },
154
154
  ...failure.transport === void 0 ? {} : { transport: failure.transport },
155
- ...failure.origin_code === void 0 ? {} : { originCode: failure.origin_code },
156
- ...failure.previous_process_exit === void 0 ? {} : { previousProcessExit: failure.previous_process_exit }
155
+ ...failure.origin_code === void 0 ? {} : { originCode: failure.origin_code }
157
156
  });
158
- /** What a row's metadata adds for its type: a failure, a delivery, an exit reason. */
157
+ /** What a row's metadata adds for its type: a failure or a delivery. */
159
158
  const eventDetails = ({ type, metadata }) => ({
160
159
  ...metadata.http_response !== void 0 ? { httpResponse: {
161
160
  resource: metadata.http_response.resource,
@@ -167,8 +166,7 @@ const eventDetails = ({ type, metadata }) => ({
167
166
  } } : {},
168
167
  ...type === "UPDATE_FAILED" && metadata.failure !== void 0 ? { failure: toFailure(metadata.failure) } : {},
169
168
  ...type === "UPDATE_DOWNLOADED" && metadata.delivery !== void 0 ? { delivery: metadata.delivery } : {},
170
- ...type === "UPDATE_DOWNLOADED" && metadata.patch_fallback === true ? { patchFallback: true } : {},
171
- ...type === "RECOVERED" && metadata.previous_process_exit !== void 0 ? { previousProcessExit: metadata.previous_process_exit } : {}
169
+ ...type === "UPDATE_DOWNLOADED" && metadata.patch_fallback === true ? { patchFallback: true } : {}
172
170
  });
173
171
  const toEventHistoryRow = (row) => ({
174
172
  ...row.to_release_id == null ? {} : { toReleaseId: row.to_release_id },
@@ -152,10 +152,9 @@ const toFailure = (failure) => ({
152
152
  ...failure.resource === void 0 ? {} : { resource: failure.resource },
153
153
  ...failure.http_status === void 0 ? {} : { httpStatus: failure.http_status },
154
154
  ...failure.transport === void 0 ? {} : { transport: failure.transport },
155
- ...failure.origin_code === void 0 ? {} : { originCode: failure.origin_code },
156
- ...failure.previous_process_exit === void 0 ? {} : { previousProcessExit: failure.previous_process_exit }
155
+ ...failure.origin_code === void 0 ? {} : { originCode: failure.origin_code }
157
156
  });
158
- /** What a row's metadata adds for its type: a failure, a delivery, an exit reason. */
157
+ /** What a row's metadata adds for its type: a failure or a delivery. */
159
158
  const eventDetails = ({ type, metadata }) => ({
160
159
  ...metadata.http_response !== void 0 ? { httpResponse: {
161
160
  resource: metadata.http_response.resource,
@@ -167,8 +166,7 @@ const eventDetails = ({ type, metadata }) => ({
167
166
  } } : {},
168
167
  ...type === "UPDATE_FAILED" && metadata.failure !== void 0 ? { failure: toFailure(metadata.failure) } : {},
169
168
  ...type === "UPDATE_DOWNLOADED" && metadata.delivery !== void 0 ? { delivery: metadata.delivery } : {},
170
- ...type === "UPDATE_DOWNLOADED" && metadata.patch_fallback === true ? { patchFallback: true } : {},
171
- ...type === "RECOVERED" && metadata.previous_process_exit !== void 0 ? { previousProcessExit: metadata.previous_process_exit } : {}
169
+ ...type === "UPDATE_DOWNLOADED" && metadata.patch_fallback === true ? { patchFallback: true } : {}
172
170
  });
173
171
  const toEventHistoryRow = (row) => ({
174
172
  ...row.to_release_id == null ? {} : { toReleaseId: row.to_release_id },